Merge branch 'develop' of https://github.com/manzerbredes/istic-openstack into develop
This commit is contained in:
commit
a26989103d
131 changed files with 8056 additions and 1164 deletions
|
@ -11,27 +11,28 @@
|
||||||
<link rel="stylesheet" href="./css/style.css">
|
<link rel="stylesheet" href="./css/style.css">
|
||||||
|
|
||||||
|
|
||||||
<!--[if lt IE 9]>
|
<!--[if lt IE 9]>
|
||||||
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
||||||
<![endif]-->
|
<![endif]-->
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
<!-- Overlay -->
|
||||||
|
<div ng-include="'./partials/login.html'"></div>
|
||||||
|
<div ng-include="'./partials/home/machineDetails.html'"></div>
|
||||||
|
<div ng-include="'./partials/loading.html'"></div>
|
||||||
|
<div ng-include="'./partials/image/upload.html'"></div>
|
||||||
|
|
||||||
|
|
||||||
<!-- MAIN GRID -->
|
<!-- MAIN GRID -->
|
||||||
<div class="container-lg">
|
<div class="container-lg">
|
||||||
<!-- Status bar -->
|
<!-- Status bar -->
|
||||||
<div class="row" ng-controller="statusCtrl">
|
<div class="row" ng-controller="statusCtrl">
|
||||||
<div class="col-lg-12">
|
<div class="col-lg-12">
|
||||||
<!-- Login Overlay -->
|
<!-- Status bar -->
|
||||||
<div ng-include="'./partials/login.html'"></div>
|
<div ng-include="'./partials/status.html'"></div>
|
||||||
<!-- Machine Details Overlay -->
|
|
||||||
<div ng-include="'./partials/home/machineDetails.html'"></div>
|
|
||||||
<div ng-include="'./partials/loading.html'"></div>
|
|
||||||
|
|
||||||
<!-- Nav -->
|
|
||||||
<div ng-include="'./partials/nav.html'"></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- Page content -->
|
<!-- Page content -->
|
||||||
|
@ -56,7 +57,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -65,7 +66,7 @@
|
||||||
|
|
||||||
<!-- Include JQuery -->
|
<!-- Include JQuery -->
|
||||||
<script src="./vendors/jquery/jquery-2.2.0.min.js"></script>
|
<script src="./vendors/jquery/jquery-2.2.0.min.js"></script>
|
||||||
|
|
||||||
<!-- Include Bootstrap -->
|
<!-- Include Bootstrap -->
|
||||||
<script src="./vendors/bootstrap/js/bootstrap.min.js"></script>
|
<script src="./vendors/bootstrap/js/bootstrap.min.js"></script>
|
||||||
|
|
||||||
|
@ -85,9 +86,10 @@
|
||||||
<!-- Include controller -->
|
<!-- Include controller -->
|
||||||
<script src="./js/controllers/login.js"></script>
|
<script src="./js/controllers/login.js"></script>
|
||||||
<script src="./js/controllers/status.js"></script>
|
<script src="./js/controllers/status.js"></script>
|
||||||
<script src="./js/controllers/home/main.js"></script>
|
<script src="./js/controllers/home/home.js"></script>
|
||||||
<script src="./js/controllers/home/machineDetails.js"></script>
|
<script src="./js/controllers/home/machineDetails.js"></script>
|
||||||
<script src="./js/controllers/network/main.js"></script>
|
<script src="./js/controllers/network/network.js"></script>
|
||||||
|
<script src="./js/controllers/image/image.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,12 +13,16 @@ mainApp.config(['$routeProvider', function($routeProvider){
|
||||||
|
|
||||||
$routeProvider.
|
$routeProvider.
|
||||||
when('/home',{
|
when('/home',{
|
||||||
templateUrl: 'partials/home/main.html',
|
templateUrl: 'partials/home/home.html',
|
||||||
controller: 'homeCtrl'
|
controller: 'homeCtrl'
|
||||||
}).
|
}).
|
||||||
when('/network',{
|
when('/network',{
|
||||||
templateUrl: 'partials/network/main.html',
|
templateUrl: 'partials/network/network.html',
|
||||||
controller: 'networkCtrl'
|
controller: 'networkCtrl'
|
||||||
|
}).
|
||||||
|
when('/image',{
|
||||||
|
templateUrl: 'partials/image/image.html',
|
||||||
|
controller: 'imageCtrl'
|
||||||
}).otherwise({
|
}).otherwise({
|
||||||
redirectTo: '/home'
|
redirectTo: '/home'
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,22 +3,14 @@
|
||||||
*
|
*
|
||||||
* @param {$scope} $scope The $scope service from angular
|
* @param {$scope} $scope The $scope service from angular
|
||||||
*/
|
*/
|
||||||
mainApp.controller('homeCtrl', [ '$scope', 'Compute', '$rootScope', 'Loading','Identity', function ($scope, Compute, $rootScope, Loading, Identity)
|
mainApp.controller('homeCtrl', [ '$scope', 'Compute', '$rootScope', 'Loading','Identity', 'Image', function ($scope, Compute, $rootScope, Loading, Identity, Image)
|
||||||
{
|
{
|
||||||
|
|
||||||
var callMeAfterPullData=function(data){
|
var callMeAfterPullData=function(data){
|
||||||
$scope.machines=Compute.getData().machines;
|
$scope.machines=Compute.getData().machines;
|
||||||
Loading.stop();
|
Loading.stop();
|
||||||
}
|
};
|
||||||
|
|
||||||
;
|
|
||||||
if(Compute.getData().machines == null && Identity.isAlreadyLogin()){
|
|
||||||
Loading.start();
|
|
||||||
Compute.pullData(callMeAfterPullData);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$scope.raiseShowMachineDetailsEvent=function(id){
|
$scope.raiseShowMachineDetailsEvent=function(id){
|
||||||
|
|
||||||
|
@ -26,11 +18,27 @@ mainApp.controller('homeCtrl', [ '$scope', 'Compute', '$rootScope', 'Loading','I
|
||||||
Loading.stop();
|
Loading.stop();
|
||||||
var data=Compute.getData();
|
var data=Compute.getData();
|
||||||
$rootScope.$broadcast("showMachineDetailsEvent", data.machines[id], data.axioms);
|
$rootScope.$broadcast("showMachineDetailsEvent", data.machines[id], data.axioms);
|
||||||
|
|
||||||
}
|
}
|
||||||
Loading.start();
|
Loading.start();
|
||||||
Compute.pullMachines(callback);
|
Compute.pullMachines(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(Identity.isAlreadyLogin()){
|
||||||
|
if(Compute.getData().machines == null{
|
||||||
|
Loading.start();
|
||||||
|
Compute.pullData(callMeAfterPullData);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if(Identity.isAlreadyLogin()){
|
||||||
|
callMeAfterPullData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Image.getImages(function(){});
|
||||||
|
}
|
||||||
|
|
||||||
}]);
|
}]);
|
|
@ -3,29 +3,32 @@
|
||||||
*
|
*
|
||||||
* @param {$scope} $scope The $scope service from angular
|
* @param {$scope} $scope The $scope service from angular
|
||||||
*/
|
*/
|
||||||
mainApp.controller('machineDetailsCtrl', [ '$scope', 'Compute', '$rootScope', '$timeout', function ($scope, Compute, $rootScope, $timeout)
|
mainApp.controller('machineDetailsCtrl', [ '$scope', 'Compute', '$rootScope', '$timeout', 'Identity', function ($scope, Compute, $rootScope, $timeout, Identity)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
// Init scope
|
||||||
$scope.machine={};
|
$scope.machine={};
|
||||||
$("#waitingForToggleMachine").hide();
|
$scope.machineIsStarting=false; // For loading icon
|
||||||
|
|
||||||
|
|
||||||
$scope.$on('showMachineDetailsEvent', function(eventName ,machine, axioms){
|
$scope.$on('showMachineDetailsEvent', function(eventName ,machine, axioms){
|
||||||
$scope.machine=machine;
|
$scope.machine=machine;
|
||||||
$scope.axioms=axioms;
|
$scope.axioms=axioms;
|
||||||
console.log(machine);
|
|
||||||
$('#machineDetailsModal').modal({backdrop: false, keyboard: true});
|
$('#machineDetailsModal').modal({backdrop: false, keyboard: true});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
$scope.toggleMachineState=function(){
|
$scope.toggleMachineState=function(){
|
||||||
$("#waitingForToggleMachine").show();
|
// Display gif
|
||||||
|
$scope.machineIsStarting=true;
|
||||||
|
|
||||||
// Fake timeout
|
// Fake timeout
|
||||||
$timeout(function(){
|
$timeout(function(){
|
||||||
$("#waitingForToggleMachine").hide();
|
$scope.machineIsStarting=false;
|
||||||
}, 3000);
|
}, 3000);
|
||||||
$timeout(function(){
|
$timeout(function(){
|
||||||
$scope.machine.online=!$scope.machine.online;
|
$scope.machine.online=!$scope.machine.online;
|
||||||
|
|
||||||
}, 3000);
|
}, 3000);
|
||||||
|
|
||||||
|
@ -35,7 +38,7 @@ mainApp.controller('machineDetailsCtrl', [ '$scope', 'Compute', '$rootScope', '$
|
||||||
$scope.applyModifications=function(){
|
$scope.applyModifications=function(){
|
||||||
//Todo
|
//Todo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}]);
|
}]);
|
||||||
|
|
29
client/js/controllers/image/image.js
Normal file
29
client/js/controllers/image/image.js
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/**
|
||||||
|
* The image controller
|
||||||
|
*
|
||||||
|
* @param {$scope} $scope The $scope service from angular
|
||||||
|
*/
|
||||||
|
mainApp.controller('imageCtrl', ['$scope', 'Image', 'Loading', 'Identity', function ($scope, Image, Loading, Identity)
|
||||||
|
{
|
||||||
|
|
||||||
|
var callbackTest=function(){
|
||||||
|
$scope.images=Image.getData().images;
|
||||||
|
Loading.stop();
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.doUpload = function () {
|
||||||
|
Image.uploadImage($scope.myFile,function(){});
|
||||||
|
};
|
||||||
|
|
||||||
|
if(Identity.isAlreadyLogin()){
|
||||||
|
|
||||||
|
if(Image.getData().images==null){
|
||||||
|
Loading.start();
|
||||||
|
Image.getImages(callbackTest);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
callbackTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}]);
|
|
@ -16,10 +16,11 @@ mainApp.controller('loginCtrl', ['$scope','$sce','Identity', function ($scope,$s
|
||||||
|
|
||||||
// Manager logout event
|
// Manager logout event
|
||||||
$scope.$on('logoutEvent', function(){
|
$scope.$on('logoutEvent', function(){
|
||||||
Identity.logout();
|
|
||||||
$('#loginModal').modal({backdrop: 'static', keyboard: false});
|
$('#loginModal').modal({backdrop: 'static', keyboard: false});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Hide loading button and message alert
|
// Hide loading button and message alert
|
||||||
$('#loadingLoginButton').hide();
|
$('#loadingLoginButton').hide();
|
||||||
$('#failedToLoginAlert').hide();
|
$('#failedToLoginAlert').hide();
|
||||||
|
|
|
@ -9,12 +9,13 @@
|
||||||
mainApp.controller('statusCtrl', ['$scope','Identity', '$rootScope', function ($scope, Identity, $rootScope)
|
mainApp.controller('statusCtrl', ['$scope','Identity', '$rootScope', function ($scope, Identity, $rootScope)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
// Give profile to model
|
// Give profile to model
|
||||||
$scope.profile=Identity.getProfile();
|
$scope.profile=Identity.getProfile();
|
||||||
|
|
||||||
// Function to logout
|
// Function to logout
|
||||||
$scope.raiseLogoutEvent=function(){
|
$scope.logout=function(){
|
||||||
$rootScope.$broadcast('logoutEvent');
|
Identity.logout();
|
||||||
};
|
};
|
||||||
|
|
||||||
}]);
|
}]);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
mainApp.factory('Identity',[ '$http', '$cookies', function($http, $cookies){
|
mainApp.factory('Identity',[ '$http', '$cookies', function($http, $cookies){
|
||||||
|
|
||||||
/* Create profile structure to store informations
|
/* Create profile structure to store informations
|
||||||
* about current session
|
* about current session
|
||||||
|
@ -27,9 +27,12 @@ mainApp.factory('Identity',[ '$http', '$cookies', function($http, $cookies){
|
||||||
&& typeof tokenPart_1InCookie !== 'undefined'
|
&& typeof tokenPart_1InCookie !== 'undefined'
|
||||||
){
|
){
|
||||||
|
|
||||||
// If yes, put it into variables
|
if(token!==null){
|
||||||
angular.extend(profile, profileInCookie);
|
// If yes, put it into variables
|
||||||
token=tokenPart_0InCookie+tokenPart_1InCookie;
|
angular.extend(profile, profileInCookie);
|
||||||
|
token=tokenPart_0InCookie+tokenPart_1InCookie;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Return I'm Login
|
// Return I'm Login
|
||||||
return true;
|
return true;
|
||||||
|
@ -51,6 +54,9 @@ mainApp.factory('Identity',[ '$http', '$cookies', function($http, $cookies){
|
||||||
token=null;
|
token=null;
|
||||||
profile.username=null;
|
profile.username=null;
|
||||||
profile.projectname=null;
|
profile.projectname=null;
|
||||||
|
|
||||||
|
// Reload Page
|
||||||
|
location.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -95,6 +101,7 @@ mainApp.factory('Identity',[ '$http', '$cookies', function($http, $cookies){
|
||||||
else{
|
else{
|
||||||
requestParserResult.failReason="Please check your username, password and project name !";
|
requestParserResult.failReason="Please check your username, password and project name !";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return requestParserResult;
|
return requestParserResult;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,27 +1,76 @@
|
||||||
|
|
||||||
mainApp.factory('Image',[ '$http', 'Identity', function($http, Identity){
|
mainApp.factory('Image',[ '$http', 'Identity', function($http, Identity){
|
||||||
|
|
||||||
|
var data={};
|
||||||
|
data.images=null;
|
||||||
|
|
||||||
|
|
||||||
var parseUploadImageAnswer=function(response, failedToSendRequest){
|
var parseUploadImageAnswer=function(response, failedToSendRequest){
|
||||||
|
|
||||||
|
// Defined return object
|
||||||
|
var requestParserResult={};
|
||||||
|
requestParserResult.status=1;
|
||||||
|
requestParserResult.failReason=null;
|
||||||
|
|
||||||
|
|
||||||
|
if (typeof response.data.Images !== 'undefined') {
|
||||||
|
// Set status code
|
||||||
|
requestParserResult.status=0;
|
||||||
|
data.images=response.data.Images;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(failedToSendRequest){
|
||||||
|
requestParserResult.failReason="Failed to send request";
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
requestParserResult.failReason="Error";
|
||||||
|
}
|
||||||
|
return requestParserResult;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
var getImages=function(callback){
|
var getImages=function(callback){
|
||||||
|
|
||||||
var result=$http.post('../server/index.php',
|
var result=$http.post('../server/index.php',
|
||||||
$.param({"token" : Identity.profile.token, "task" : "Image"}));
|
$.param({"token" : Identity.getToken(), "task" : "image", 'action':'listImage'}));
|
||||||
|
|
||||||
|
// Wait and handle the response
|
||||||
|
result.then(function (response){
|
||||||
|
callback(parseUploadImageAnswer(response, false));
|
||||||
|
},function(response){
|
||||||
|
callback(parseUploadImageAnswer(response, true));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var uploadImage=function(fileToUpload, callback) {
|
||||||
|
|
||||||
|
|
||||||
|
var result=$http.post('../server/index.php',
|
||||||
|
$.param({"token" : Identity.getToken(), "task" : "image", 'action':'uploadImage', 'filename':fileToUpload, 'id':'6564'}));
|
||||||
|
|
||||||
|
// Wait and handle the response
|
||||||
|
result.then(function (response){
|
||||||
|
callback(parseUploadImageAnswer(response, false));
|
||||||
|
},function(response){
|
||||||
|
callback(parseUploadImageAnswer(response, true));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var getData=function(response){
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
// Return services objects
|
// Return services objects
|
||||||
return {
|
return {
|
||||||
uploadImage: uploadImage
|
getImages:getImages,
|
||||||
|
getData:getData,
|
||||||
|
uploadImage:uploadImage
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,23 @@
|
||||||
|
|
||||||
mainApp.factory('Loading',[ '$http', 'Identity', function($http, Identity){
|
mainApp.factory('Loading',[ function(){
|
||||||
|
/**
|
||||||
|
* Display Loading modal
|
||||||
|
*/
|
||||||
|
|
||||||
var start=function(){
|
var start=function(){
|
||||||
$('#loadingModal').modal({backdrop: 'static', keyboard: false});
|
$('#loadingModal').modal({backdrop: 'static', keyboard: false});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide Loading modal
|
||||||
|
*/
|
||||||
var stop=function(){
|
var stop=function(){
|
||||||
$('#loadingModal').modal('hide');
|
$('#loadingModal').modal('hide');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Service returns
|
||||||
return {
|
return {
|
||||||
start:start,
|
start:start,
|
||||||
stop:stop
|
stop:stop
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}]);
|
}]);
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
<button class="btn btn-danger" ng-if="machine.status=='ACTIVE'" ng-click="toggleMachineState()">Turn Off</button>
|
<button class="btn btn-danger" ng-if="machine.status=='ACTIVE'" ng-click="toggleMachineState()">Turn Off</button>
|
||||||
<button class="btn btn-success" ng-if="machine.status!=='ACTIVE'" ng-click="toggleMachineState()">Turn On</button>
|
<button class="btn btn-success" ng-if="machine.status!=='ACTIVE'" ng-click="toggleMachineState()">Turn On</button>
|
||||||
<img src="images/spin/32x32/Preloader_1.gif" id="waitingForToggleMachine"></span>
|
<img src="images/spin/32x32/Preloader_1.gif" ng-if="machineIsStarting"></span>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
38
client/partials/image/image.html
Normal file
38
client/partials/image/image.html
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
|
||||||
|
|
||||||
|
<div class="panel panel-default" ng-controller="imageCtrl">
|
||||||
|
<div class="panel-heading">
|
||||||
|
Image Manager
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
|
||||||
|
|
||||||
|
<div class="btn-group btn-group-md" role="group" aria-label="...">
|
||||||
|
<button type="button" class="btn btn-default" data-toggle="modal" data-target="#uploadImageModal"">Upload</button>
|
||||||
|
<button type="button" class="btn btn-default">Download</button>
|
||||||
|
</div>
|
||||||
|
<p></p>
|
||||||
|
<table class="table table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Size</th>
|
||||||
|
<th>Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr ng-repeat="image in images">
|
||||||
|
<td>{{ image.name }}</td>
|
||||||
|
<td>{{ (image.size / 1048576).toFixed(2) }} MB</td>
|
||||||
|
<td><button type="button" class="btn btn-danger">Remove</button></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
25
client/partials/image/upload.html
Normal file
25
client/partials/image/upload.html
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<div class="modal fade" id="uploadImageModal" ng-controller="loginCtrl">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content"></div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<!--<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>-->
|
||||||
|
<h4 class="modal-title">Upload Image</h4>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-body">
|
||||||
|
|
||||||
|
<label class="control-label">Select File</label>
|
||||||
|
<input id="input-1" type="file" class="file">
|
||||||
|
<p></p>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<!--<a href="#" data-dismiss="modal" class="btn btn-default">Close</a>-->
|
||||||
|
|
||||||
|
<a href="#" class="btn btn-lg btn-primary btn-block" id="loginButton">Upload</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -1,4 +1,5 @@
|
||||||
<div class="list-group">
|
<div class="list-group">
|
||||||
<a href="#/home" class="list-group-item">Home</a>
|
<a href="#/home" class="list-group-item">Home</a>
|
||||||
<a href="#/network" class="list-group-item">Network</a>
|
<a href="#/network" class="list-group-item">Network</a>
|
||||||
</div>
|
<a href="#/image" class="list-group-item">Images</a>
|
||||||
|
</div>
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
<nav class="navbar navbar-default">
|
|
||||||
<div class="container-fluid">
|
|
||||||
<!-- Brand and toggle get grouped for better mobile display -->
|
|
||||||
<div class="navbar-header">
|
|
||||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
|
|
||||||
<span class="sr-only">Toggle navigation</span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
</button>
|
|
||||||
<a class="navbar-brand" href="#"><b>Status</b></a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="navbar-"></div>
|
|
||||||
|
|
||||||
<!-- Collect the nav links, forms, and other content for toggling -->
|
|
||||||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
|
||||||
|
|
||||||
<ul class="nav navbar-nav">
|
|
||||||
<li class="nav-divider"></li>
|
|
||||||
<li><a href="#">User : {{ profile.username }}</a></li>
|
|
||||||
<li><a href="#">Project Name : {{ profile.projectname }}</a></li>
|
|
||||||
|
|
||||||
<!--<li><a href="#" >Connection : <span ng-bind-html="connection"></span></a></li>-->
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<ul class="nav navbar-nav navbar-right">
|
|
||||||
<li class="dropdown">
|
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Account<span class="caret"></span></a>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li><a href="#">Informations</a></li>
|
|
||||||
<li><a href="#">Settings</a></li>
|
|
||||||
<li role="separator" class="divider"></li>
|
|
||||||
<li><a href="#" ng-click="raiseLogoutEvent()">Logout</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div><!-- /.navbar-collapse -->
|
|
||||||
</div><!-- /.container-fluid -->
|
|
||||||
</nav>
|
|
29
client/partials/status.html
Normal file
29
client/partials/status.html
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<nav class="navbar navbar-default">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<!-- Brand and toggle get grouped for better mobile display -->
|
||||||
|
<div class="navbar-header">
|
||||||
|
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
|
||||||
|
<span class="sr-only">Toggle navigation</span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
</button>
|
||||||
|
<a class="navbar-brand"><b>Status</b></a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="navbar-"></div>
|
||||||
|
|
||||||
|
<!-- Collect the nav links, forms, and other content for toggling -->
|
||||||
|
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||||
|
|
||||||
|
<ul class="nav navbar-nav">
|
||||||
|
<li class="nav-divider"></li>
|
||||||
|
<li><a>User : {{ profile.username }}</a></li>
|
||||||
|
<li><a>Project Name : {{ profile.projectname }}</a></li>
|
||||||
|
</ul>
|
||||||
|
<ul class="nav navbar-nav navbar-right">
|
||||||
|
<li><a ng-click="logout()">Logout</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
|
@ -0,0 +1,3 @@
|
||||||
|
<?php
|
||||||
|
phpinfo();
|
||||||
|
?>
|
|
@ -1,6 +1,12 @@
|
||||||
<?php
|
<?php
|
||||||
include_once("../core/Plugin_Api.php");
|
include_once("../core/Plugin_Api.php");
|
||||||
include_once("../core/LibOverride/genTokenOptions.php");
|
include_once("../core/LibOverride/genTokenOptions.php");
|
||||||
|
include_once("../core/ErrorManagement.php");
|
||||||
|
|
||||||
|
use OpenCloud\Common\Error\BadResponseError;
|
||||||
|
use OpenCloud\Common\Error\BaseError;
|
||||||
|
use OpenCloud\Common\Error\NotImplementedError;
|
||||||
|
use OpenCloud\Common\Error\UserInputError;
|
||||||
|
|
||||||
class AppTest{
|
class AppTest{
|
||||||
|
|
||||||
|
@ -10,6 +16,7 @@ class AppTest{
|
||||||
protected $tokenClass;
|
protected $tokenClass;
|
||||||
protected $tokenPost;
|
protected $tokenPost;
|
||||||
protected $output;
|
protected $output;
|
||||||
|
protected $errorClass;
|
||||||
|
|
||||||
public function __construct($args){
|
public function __construct($args){
|
||||||
|
|
||||||
|
@ -19,6 +26,9 @@ class AppTest{
|
||||||
$this->pluginsApi = plugin_api::getInstance();
|
$this->pluginsApi = plugin_api::getInstance();
|
||||||
$this->errorClass = new errorManagement($this);
|
$this->errorClass = new errorManagement($this);
|
||||||
$this->output = array();
|
$this->output = array();
|
||||||
|
|
||||||
|
$this->errorClass = new errorManagement($this);
|
||||||
|
|
||||||
$this->postParams = $_POST;
|
$this->postParams = $_POST;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -79,10 +89,16 @@ class AppTest{
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPostParam($name){
|
public function getPostParam($name){
|
||||||
|
|
||||||
return $this->postParams[$name];
|
return $this->postParams[$name];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setPostParam($name, $value){
|
||||||
|
|
||||||
|
$this->postParams[$name] = $value;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public function setOutput($key, $out){
|
public function setOutput($key, $out){
|
||||||
|
|
||||||
|
@ -94,4 +110,12 @@ class AppTest{
|
||||||
return json_encode($this->output);
|
return json_encode($this->output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function getErrorInstance(){
|
||||||
|
|
||||||
|
return $this->errorClass;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,35 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
require '../vendor/autoload.php';
|
include('InitTest.php');
|
||||||
include('/istic-openstack/server/init.php');
|
include_once("../core/Image.php");
|
||||||
|
|
||||||
/*
|
|
||||||
$options = Array();
|
|
||||||
$options["user"] = Array("name"=>"admin", "password"=>"ae5or6cn", "domain"=>["id"=>"Default"]);
|
|
||||||
$options["scope"] = Array("project"=>Array("name"=>"admin", "domain"=>["id"=>"Default"]));
|
|
||||||
$options["authUrl"] = "http://148.60.11.31:5000/v3";
|
|
||||||
|
|
||||||
$openstack = new OpenStack\OpenStack($options);
|
|
||||||
|
|
||||||
//$identity = $openstack->identityV3();
|
|
||||||
//var_dump($identity);
|
|
||||||
// Since usernames will not be unique across an entire OpenStack installation,
|
|
||||||
// when authenticating with them you must also provide your domain ID. You do
|
|
||||||
// not have to do this if you authenticate with a user ID.
|
|
||||||
/*$token = $identity->generateToken([
|
|
||||||
'user' => [
|
|
||||||
'name' => 'admin',
|
|
||||||
'password' => 'ae5or6cn',
|
|
||||||
'domain' => [
|
|
||||||
'id' => 'Default'
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]);
|
|
||||||
*/
|
|
||||||
//$compute = $openstack->computeV2(["region" => "RegionOne"]);
|
|
||||||
//$image= $openstack->imagesV2(["region" => "RegionOne"]);
|
|
||||||
//var_dump($compute->client);
|
|
||||||
//$servers = $compute->listServers(true);
|
|
||||||
echo 'toto';
|
|
||||||
|
|
||||||
$image = new Image($App);
|
$image = new Image($App);
|
||||||
|
|
||||||
|
@ -43,53 +14,38 @@ $opt['minDisk'] = 1;
|
||||||
$opt['protected'] = false;
|
$opt['protected'] = false;
|
||||||
$opt['minRam'] = 10;
|
$opt['minRam'] = 10;
|
||||||
|
|
||||||
//$new_image = $image->create_image($opt);
|
//$App->setPostParam('id', 'sdfihlus154dfhj');
|
||||||
|
//$err = $image->action("createImage");
|
||||||
|
|
||||||
|
|
||||||
//Liste des images
|
//Liste des images
|
||||||
$images = $image->list_images();
|
$image->action("listImage");
|
||||||
|
$im = $App->show();
|
||||||
|
$images = json_decode($im, true)["Images"];
|
||||||
|
$recup;
|
||||||
|
|
||||||
echo "Images présentes :";
|
echo "Images présentes :";
|
||||||
echo "</br>";
|
echo "</br>";
|
||||||
|
|
||||||
foreach($images as $i){
|
foreach($images as $i){
|
||||||
echo $i->name;
|
$recup = $i;
|
||||||
if($i->name == "Test"){
|
echo $recup['name'];
|
||||||
$id_image = $i->id;
|
|
||||||
$list = $i->tags;
|
|
||||||
echo $i->status;
|
|
||||||
}
|
|
||||||
echo "</br>";
|
echo "</br>";
|
||||||
}
|
//echo $recup['id'];
|
||||||
|
}
|
||||||
echo "</br>";
|
echo "</br>";
|
||||||
|
echo "Erreur capturée: ";
|
||||||
|
echo "</br>";
|
||||||
|
|
||||||
|
/*
|
||||||
|
$App->setPostParam('id', 354);
|
||||||
|
$err = $image->action("deleteImage");
|
||||||
|
$temp = $App->show();
|
||||||
|
$ret = json_decode($temp, true)["Images"];
|
||||||
|
echo $ret['id'];
|
||||||
|
*/
|
||||||
|
|
||||||
if(isset($list)){
|
|
||||||
foreach ($list as $l) {
|
|
||||||
echo $l;
|
|
||||||
echo "</br>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Détails Image
|
|
||||||
//$details = $image->image_details($id_image);
|
|
||||||
|
|
||||||
//$image->delete_image('123456');
|
|
||||||
|
|
||||||
//$image->desactivate_image($id_image);
|
|
||||||
//$image->reactivate_image($id_image);
|
|
||||||
|
|
||||||
//$file_name = "/home/yogg/Downloads/TinyCore-6.4.1.iso";
|
|
||||||
//$image->upload_image($id_image, $file_name);
|
|
||||||
|
|
||||||
//$image->download_image($id_image);
|
|
||||||
|
|
||||||
/*
|
|
||||||
$opt_update = Array();
|
|
||||||
$opt_update['name'] = "Test";
|
|
||||||
$opt_update['tags'] = null;
|
|
||||||
|
|
||||||
$update = $image->update_image($id_image, $opt_update);
|
|
||||||
echo $update->name;
|
|
||||||
*/
|
|
||||||
|
|
||||||
?>
|
?>
|
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"require": {
|
"require": {
|
||||||
"php-opencloud/openstack": "dev-master"
|
"php-opencloud/openstack": "dev-master",
|
||||||
|
"php-opencloud/common": "dev-master"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
98
server/composer.lock
generated
98
server/composer.lock
generated
|
@ -4,8 +4,8 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"hash": "e7cbd5d3df36fb1a3f3378b837068196",
|
"hash": "7647ed348aee68f2db6b71e4d2fb1fe7",
|
||||||
"content-hash": "125e4702f7a417475a4150c889ac6c3d",
|
"content-hash": "82731500d050a65f09e92b70c1f96ea9",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "guzzlehttp/guzzle",
|
"name": "guzzlehttp/guzzle",
|
||||||
|
@ -71,16 +71,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "guzzlehttp/promises",
|
"name": "guzzlehttp/promises",
|
||||||
"version": "1.0.3",
|
"version": "1.1.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/guzzle/promises.git",
|
"url": "https://github.com/guzzle/promises.git",
|
||||||
"reference": "b1e1c0d55f8083c71eda2c28c12a228d708294ea"
|
"reference": "bb9024c526b22f3fe6ae55a561fd70653d470aa8"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/guzzle/promises/zipball/b1e1c0d55f8083c71eda2c28c12a228d708294ea",
|
"url": "https://api.github.com/repos/guzzle/promises/zipball/bb9024c526b22f3fe6ae55a561fd70653d470aa8",
|
||||||
"reference": "b1e1c0d55f8083c71eda2c28c12a228d708294ea",
|
"reference": "bb9024c526b22f3fe6ae55a561fd70653d470aa8",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -118,20 +118,20 @@
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"promise"
|
"promise"
|
||||||
],
|
],
|
||||||
"time": "2015-10-15 22:28:00"
|
"time": "2016-03-08 01:15:46"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "guzzlehttp/psr7",
|
"name": "guzzlehttp/psr7",
|
||||||
"version": "1.2.2",
|
"version": "1.2.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/guzzle/psr7.git",
|
"url": "https://github.com/guzzle/psr7.git",
|
||||||
"reference": "f5d04bdd2881ac89abde1fb78cc234bce24327bb"
|
"reference": "2e89629ff057ebb49492ba08e6995d3a6a80021b"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/guzzle/psr7/zipball/f5d04bdd2881ac89abde1fb78cc234bce24327bb",
|
"url": "https://api.github.com/repos/guzzle/psr7/zipball/2e89629ff057ebb49492ba08e6995d3a6a80021b",
|
||||||
"reference": "f5d04bdd2881ac89abde1fb78cc234bce24327bb",
|
"reference": "2e89629ff057ebb49492ba08e6995d3a6a80021b",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -176,7 +176,7 @@
|
||||||
"stream",
|
"stream",
|
||||||
"uri"
|
"uri"
|
||||||
],
|
],
|
||||||
"time": "2016-01-23 01:23:02"
|
"time": "2016-02-18 21:54:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "justinrainbow/json-schema",
|
"name": "justinrainbow/json-schema",
|
||||||
|
@ -245,28 +245,27 @@
|
||||||
"time": "2016-01-25 15:43:01"
|
"time": "2016-01-25 15:43:01"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "php-opencloud/openstack",
|
"name": "php-opencloud/common",
|
||||||
"version": "dev-master",
|
"version": "dev-master",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/php-opencloud/openstack.git",
|
"url": "https://github.com/php-opencloud/common.git",
|
||||||
"reference": "15aca73f423166c7ef8337ba08615c103c66e931"
|
"reference": "fd027b817c3dd8f83b0c8d9fb1df34ebf25f8c62"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/php-opencloud/openstack/zipball/15aca73f423166c7ef8337ba08615c103c66e931",
|
"url": "https://api.github.com/repos/php-opencloud/common/zipball/fd027b817c3dd8f83b0c8d9fb1df34ebf25f8c62",
|
||||||
"reference": "15aca73f423166c7ef8337ba08615c103c66e931",
|
"reference": "fd027b817c3dd8f83b0c8d9fb1df34ebf25f8c62",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"guzzlehttp/guzzle": "~6.1",
|
"guzzlehttp/guzzle": "~6.1",
|
||||||
"justinrainbow/json-schema": "~1.3",
|
"justinrainbow/json-schema": "~1.3",
|
||||||
"php": ">=5.6"
|
"php": "~7.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"fabpot/php-cs-fixer": "~1.0",
|
"fabpot/php-cs-fixer": "~1.0",
|
||||||
"jakub-onderka/php-parallel-lint": "0.*",
|
"jakub-onderka/php-parallel-lint": "0.*",
|
||||||
"phpspec/prophecy-phpunit": "~1.0",
|
|
||||||
"phpunit/phpunit": "~4.0",
|
"phpunit/phpunit": "~4.0",
|
||||||
"psr/log": "~1.0",
|
"psr/log": "~1.0",
|
||||||
"sami/sami": "dev-master",
|
"sami/sami": "dev-master",
|
||||||
|
@ -275,9 +274,9 @@
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"OpenStack\\": "src/",
|
"OpenCloud\\": "src/",
|
||||||
"OpenStack\\Test\\": "tests/unit/",
|
"OpenCloud\\Test\\": "tests/unit/",
|
||||||
"OpenStack\\Integration\\": "tests/integration/"
|
"OpenCloud\\Integration\\": "tests/integration/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
@ -288,7 +287,57 @@
|
||||||
"homepage": "https://github.com/jamiehannaford"
|
"homepage": "https://github.com/jamiehannaford"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2016-01-25 10:35:10"
|
"time": "2016-03-08 12:56:34"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "php-opencloud/openstack",
|
||||||
|
"version": "dev-master",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/php-opencloud/openstack.git",
|
||||||
|
"reference": "f2ee77024843659d970817a9e7055bb40a3724f9"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
<<<<<<< HEAD
|
||||||
|
<<<<<<< Updated upstream
|
||||||
|
"url": "https://api.github.com/repos/php-opencloud/openstack/zipball/15aca73f423166c7ef8337ba08615c103c66e931",
|
||||||
|
=======
|
||||||
|
"url": "https://api.github.com/repos/php-opencloud/openstack/zipball/f2ee77024843659d970817a9e7055bb40a3724f9",
|
||||||
|
>>>>>>> develop
|
||||||
|
"reference": "15aca73f423166c7ef8337ba08615c103c66e931",
|
||||||
|
=======
|
||||||
|
"url": "https://api.github.com/repos/php-opencloud/openstack/zipball/f2ee77024843659d970817a9e7055bb40a3724f9",
|
||||||
|
"reference": "f2ee77024843659d970817a9e7055bb40a3724f9",
|
||||||
|
>>>>>>> Stashed changes
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php-opencloud/common": "dev-master"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"fabpot/php-cs-fixer": "~1.0",
|
||||||
|
"jakub-onderka/php-parallel-lint": "0.*",
|
||||||
|
"phpunit/phpunit": "~4.0",
|
||||||
|
"psr/log": "~1.0",
|
||||||
|
"sami/sami": "dev-master",
|
||||||
|
"satooshi/php-coveralls": "~1.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"OpenStack\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Jamie Hannaford",
|
||||||
|
"email": "jamie.hannaford@rackspace.com",
|
||||||
|
"homepage": "https://github.com/jamiehannaford"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2016-03-08 14:37:14"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "psr/http-message",
|
"name": "psr/http-message",
|
||||||
|
@ -344,7 +393,8 @@
|
||||||
"aliases": [],
|
"aliases": [],
|
||||||
"minimum-stability": "stable",
|
"minimum-stability": "stable",
|
||||||
"stability-flags": {
|
"stability-flags": {
|
||||||
"php-opencloud/openstack": 20
|
"php-opencloud/openstack": 20,
|
||||||
|
"php-opencloud/common": 20
|
||||||
},
|
},
|
||||||
"prefer-stable": false,
|
"prefer-stable": false,
|
||||||
"prefer-lowest": false,
|
"prefer-lowest": false,
|
||||||
|
|
|
@ -3,10 +3,10 @@ include_once("core/Plugin_Api.php");
|
||||||
include_once("core/LibOverride/genTokenOptions.php");
|
include_once("core/LibOverride/genTokenOptions.php");
|
||||||
include_once("core/ErrorManagement.php");
|
include_once("core/ErrorManagement.php");
|
||||||
|
|
||||||
use OpenStack\Common\Error\BadResponseError;
|
use OpenCloud\Common\Error\BadResponseError;
|
||||||
use OpenStack\Common\Error\BaseError;
|
use OpenCloud\Common\Error\BaseError;
|
||||||
use OpenStack\Common\Error\NotImplementedError;
|
use OpenCloud\Common\Error\NotImplementedError;
|
||||||
use OpenStack\Common\Error\UserInputError;
|
use OpenCloud\Common\Error\UserInputError;
|
||||||
|
|
||||||
class App{
|
class App{
|
||||||
|
|
||||||
|
@ -56,10 +56,10 @@ class App{
|
||||||
return $this->openstack->networkingV2($opt);
|
return $this->openstack->networkingV2($opt);
|
||||||
break;
|
break;
|
||||||
case "Compute":
|
case "Compute":
|
||||||
if($this->tokenPost == NULL) $this->tokenClass->genComputeToken();
|
if($this->tokenPost == NULL) $this->tokenClass->genComputeToken();
|
||||||
$opt = $this->tokenClass->getOptions($service);
|
$opt = $this->tokenClass->getOptions($service);
|
||||||
return $this->openstack->computeV2($opt);
|
return $this->openstack->computeV2($opt);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,29 @@ class App{
|
||||||
$this->errorClass->BaseErrorHandler($e);
|
$this->errorClass->BaseErrorHandler($e);
|
||||||
}catch(NotImplementedError $e){
|
}catch(NotImplementedError $e){
|
||||||
$this->errorClass->NotImplementedHandler($e);
|
$this->errorClass->NotImplementedHandler($e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deauthenticate(){
|
||||||
|
|
||||||
|
try{
|
||||||
|
|
||||||
|
$this->tokenClass->revokeComputeToken();
|
||||||
|
$this->tokenClass->revokeImageToken();
|
||||||
|
$this->tokenClass->revokeNetworkToken();
|
||||||
|
$this->tokenClass->revokeIdentityToken();
|
||||||
|
|
||||||
|
$this->setOutput("deauthenticate", "Ok");
|
||||||
|
}catch(BadResponseError $e){
|
||||||
|
$this->errorClass->BadResponseHandler($e);
|
||||||
|
}catch(UserInputError $e){
|
||||||
|
$this->errorClass->UserInputHandler($e);
|
||||||
|
}catch(BaseError $e){
|
||||||
|
$this->errorClass->BaseErrorHandler($e);
|
||||||
|
}catch(NotImplementedError $e){
|
||||||
|
$this->errorClass->NotImplementedHandler($e);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
637
server/core/Compute.php
Normal file → Executable file
637
server/core/Compute.php
Normal file → Executable file
|
@ -1,7 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
//namespace istic-openstack\Server\core;
|
//namespace istic-openstack\Server\core;
|
||||||
// TODO introduce error-handling based on errors specific to the compute module
|
use OpenCloud\Common\Error;
|
||||||
use OpenStack\Common\Error;
|
|
||||||
|
|
||||||
class compute
|
class compute
|
||||||
{
|
{
|
||||||
|
@ -12,11 +11,11 @@ class compute
|
||||||
protected $libClass;
|
protected $libClass;
|
||||||
|
|
||||||
|
|
||||||
public function __construct($app)
|
public function __construct($app)
|
||||||
{
|
{
|
||||||
$this->app = $app;
|
$this->app = $app;
|
||||||
$this->libClass = $app->getLibClass("Compute");
|
$this->libClass = $app->getLibClass("Compute");
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Execute an action
|
* Execute an action
|
||||||
*
|
*
|
||||||
|
@ -35,21 +34,51 @@ class compute
|
||||||
*/
|
*/
|
||||||
public function listServers()
|
public function listServers()
|
||||||
{
|
{
|
||||||
$serverList = $this->libClass->listServers(true);
|
try{
|
||||||
$servers = Array();
|
$serverList = $this->libClass->listServers(true);
|
||||||
foreach($serverList as $server){
|
$servers = Array();
|
||||||
$servers[$server->id] = Array();
|
foreach($serverList as $server){
|
||||||
$server->flavor->retrieve();
|
$servers[$server->id] = Array();
|
||||||
$server->image->retrieve();
|
$server->flavor->retrieve();
|
||||||
$servers[$server->id]["id"] = $server->id;
|
$server->image->retrieve();
|
||||||
$servers[$server->id]["name"] = $server->name;
|
$server->retrieve();
|
||||||
$servers[$server->id]["imageId"] = $server->image->id;
|
$servers[$server->id]["id"] = $server->id;
|
||||||
$servers[$server->id]["flavorId"] = $server->flavor->id;
|
$servers[$server->id]["name"] = $server->name;
|
||||||
$servers[$server->id]["status"] = $server->status;
|
$servers[$server->id]["image"] = $server->image;
|
||||||
$servers[$server->id]["ram"] = $server->flavor->ram;
|
$servers[$server->id]["ram"] = $server->flavor->ram;
|
||||||
$servers[$server->id]["disk"] = $server->flavor->disk;
|
$servers[$server->id]["disk"] = $server->flavor->disk;
|
||||||
|
$servers[$server->id]["flavor"] = $server->flavor;
|
||||||
|
$servers[$server->id]["status"] = $server->status;
|
||||||
|
$servers[$server->id]["created"] = $server->created;
|
||||||
|
$servers[$server->id]["updated"] = $server->updated;
|
||||||
|
$servers[$server->id]["ipv4"] = $server->ipv4;
|
||||||
|
$servers[$server->id]["ipv6"] = $server->ipv6;
|
||||||
|
$servers[$server->id]["progress"] = $server->progress;
|
||||||
|
$servers[$server->id]["hostId"] = $server->hostId;
|
||||||
|
$servers[$server->id]["tenantId"] = $server->tenantId;
|
||||||
|
$servers[$server->id]["userId"] = $server->userId;
|
||||||
|
$servers[$server->id]["taskState"] = $server->taskState;
|
||||||
|
$servers[$server->id]["addresses"] = $server->addresses;
|
||||||
|
$servers[$server->id]["links"] = $server->links;
|
||||||
|
$servers[$server->id]["metadata"] = $server->metadata;
|
||||||
|
}
|
||||||
|
$this->app->setOutput("Servers", $servers);
|
||||||
}
|
}
|
||||||
$this->app->setOutput("Servers", $servers);
|
catch(BadResponseError $e){
|
||||||
|
$this->app->getErrorInstance()->BadResponseHandler($e);
|
||||||
|
}
|
||||||
|
catch(UserInputError $e){
|
||||||
|
$this->app->getErrorInstance()->UserInputHandler($e);
|
||||||
|
}
|
||||||
|
catch(BaseError $e){
|
||||||
|
$this->app->getErrorInstance()->BaseErrorHandler($e);
|
||||||
|
}
|
||||||
|
catch(NotImplementedError $e){
|
||||||
|
$this->app->getErrorInstance()->NotImplementedHandler($e);
|
||||||
|
}
|
||||||
|
catch(Exception $e){
|
||||||
|
$this->app->getErrorInstance()->OtherException($e);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -58,14 +87,36 @@ class compute
|
||||||
*/
|
*/
|
||||||
public function listFlavors()
|
public function listFlavors()
|
||||||
{
|
{
|
||||||
$flavorList = $this->libClass->listFlavors();
|
try{
|
||||||
$flavors = Array();
|
$flavorList = $this->libClass->listFlavors();
|
||||||
foreach($flavorList as $flavor){
|
$flavors = Array();
|
||||||
$flavors[$flavor->id] = Array();
|
foreach($flavorList as $flavor){
|
||||||
$flavors[$flavor->id]["id"] = $flavor->id;
|
$flavors[$flavor->id] = Array();
|
||||||
$flavors[$flavor->id]["name"] = $flavor->name;
|
$flavor->retrieve();
|
||||||
|
$flavors[$flavor->id]["id"] = $flavor->id;
|
||||||
|
$flavors[$flavor->id]["name"] = $flavor->name;
|
||||||
|
$flavors[$flavor->id]["ram"] = $flavor->ram;
|
||||||
|
$flavors[$flavor->id]["disk"] = $flavor->disk;
|
||||||
|
$flavors[$flavor->id]["vcpus"] = $flavor->vcpus;
|
||||||
|
$flavors[$flavor->id]["links"] = $flavor->links;
|
||||||
}
|
}
|
||||||
$this->app->setOutput("Flavors", $flavors);
|
$this->app->setOutput("Flavors", $flavors);
|
||||||
|
}
|
||||||
|
catch(BadResponseError $e){
|
||||||
|
$this->app->getErrorInstance()->BadResponseHandler($e);
|
||||||
|
}
|
||||||
|
catch(UserInputError $e){
|
||||||
|
$this->app->getErrorInstance()->UserInputHandler($e);
|
||||||
|
}
|
||||||
|
catch(BaseError $e){
|
||||||
|
$this->app->getErrorInstance()->BaseErrorHandler($e);
|
||||||
|
}
|
||||||
|
catch(NotImplementedError $e){
|
||||||
|
$this->app->getErrorInstance()->NotImplementedHandler($e);
|
||||||
|
}
|
||||||
|
catch(Exception $e){
|
||||||
|
$this->app->getErrorInstance()->OtherException($e);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -74,37 +125,74 @@ class compute
|
||||||
*/
|
*/
|
||||||
public function listImages()
|
public function listImages()
|
||||||
{
|
{
|
||||||
$imageList = $this->libClass->listImages();
|
try{
|
||||||
$images = Array();
|
$imageList = $this->libClass->listImages();
|
||||||
foreach($imageList as $image){
|
$images = Array();
|
||||||
$images[$image->id] = Array();
|
foreach($imageList as $image){
|
||||||
$images[$image->id]["id"] = $image->id;
|
$images[$image->id] = Array();
|
||||||
$images[$image->id]["name"] = $image->name;
|
$image->retrieve();
|
||||||
|
$images[$image->id]["id"] = $image->id;
|
||||||
|
$images[$image->id]["name"] = $image->name;
|
||||||
|
$images[$image->id]["status"] = $image->status;
|
||||||
|
$images[$image->id]["created"] = $image->created;
|
||||||
|
$images[$image->id]["updated"] = $image->updated;
|
||||||
|
$images[$image->id]["minDisk"] = $image->minDisk;
|
||||||
|
$images[$image->id]["minRam"] = $image->minRam;
|
||||||
|
$images[$image->id]["progress"] = $image->progress;
|
||||||
|
$images[$image->id]["links"] = $image->links;
|
||||||
|
$images[$image->id]["metadata"] = $image->metadata;
|
||||||
}
|
}
|
||||||
$this->app->setOutput("Images", $images);
|
$this->app->setOutput("Images", $images);
|
||||||
|
}
|
||||||
|
catch(BadResponseError $e){
|
||||||
|
$this->app->getErrorInstance()->BadResponseHandler($e);
|
||||||
|
}
|
||||||
|
catch(UserInputError $e){
|
||||||
|
$this->app->getErrorInstance()->UserInputHandler($e);
|
||||||
|
}
|
||||||
|
catch(BaseError $e){
|
||||||
|
$this->app->getErrorInstance()->BaseErrorHandler($e);
|
||||||
|
}
|
||||||
|
catch(NotImplementedError $e){
|
||||||
|
$this->app->getErrorInstance()->NotImplementedHandler($e);
|
||||||
|
}
|
||||||
|
catch(Exception $e){
|
||||||
|
$this->app->getErrorInstance()->OtherException($e);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Create server.
|
|
||||||
* @return array
|
|
||||||
*
|
|
||||||
public function createServer()
|
|
||||||
{
|
|
||||||
|
|
||||||
$server = $this->libClass->createServer();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* Get server details.
|
* Get server details.
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getServer()
|
public function getServer()
|
||||||
{
|
{
|
||||||
$serverId = $this->app->getPostParam("serverId");
|
try{
|
||||||
$opt = array('id' => $serverId);
|
$serverId = $this->app->getPostParam("serverId");
|
||||||
$server = $this->libClass->getServer($opt);
|
if(!isset($serverId)){
|
||||||
$server->retrieve();
|
$this->app->setOutput("Error", "Server ID is missing, son!");
|
||||||
$this->app->setOutput("MyServer", $server);
|
return;
|
||||||
|
}
|
||||||
|
$opt = array('id' => $serverId);
|
||||||
|
$server = $this->libClass->getServer($opt);
|
||||||
|
$server->retrieve();
|
||||||
|
$this->app->setOutput("MyServer", $server);
|
||||||
|
}
|
||||||
|
catch(BadResponseError $e){
|
||||||
|
$this->app->getErrorInstance()->BadResponseHandler($e);
|
||||||
|
}
|
||||||
|
catch(UserInputError $e){
|
||||||
|
$this->app->getErrorInstance()->UserInputHandler($e);
|
||||||
|
}
|
||||||
|
catch(BaseError $e){
|
||||||
|
$this->app->getErrorInstance()->BaseErrorHandler($e);
|
||||||
|
}
|
||||||
|
catch(NotImplementedError $e){
|
||||||
|
$this->app->getErrorInstance()->NotImplementedHandler($e);
|
||||||
|
}
|
||||||
|
catch(Exception $e){
|
||||||
|
$this->app->getErrorInstance()->OtherException($e);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -113,11 +201,32 @@ class compute
|
||||||
*/
|
*/
|
||||||
public function getFlavor()
|
public function getFlavor()
|
||||||
{
|
{
|
||||||
$flavorId = $this->app->getPostParam("flavorId");
|
try{
|
||||||
$opt = array('id' => $flavorId);
|
$flavorId = $this->app->getPostParam("flavorId");
|
||||||
$flavor = $this->libClass->getFlavor($opt);
|
if(!isset($serverId)){
|
||||||
$flavor->retrieve();
|
$this->app->setOutput("Error", "Flavor ID is missing, son!");
|
||||||
$this->app->setOutput("MyFlavor", $flavor);
|
return;
|
||||||
|
}
|
||||||
|
$opt = array('id' => $flavorId);
|
||||||
|
$flavor = $this->libClass->getFlavor($opt);
|
||||||
|
$flavor->retrieve();
|
||||||
|
$this->app->setOutput("MyFlavor", $flavor);
|
||||||
|
}
|
||||||
|
catch(BadResponseError $e){
|
||||||
|
$this->app->getErrorInstance()->BadResponseHandler($e);
|
||||||
|
}
|
||||||
|
catch(UserInputError $e){
|
||||||
|
$this->app->getErrorInstance()->UserInputHandler($e);
|
||||||
|
}
|
||||||
|
catch(BaseError $e){
|
||||||
|
$this->app->getErrorInstance()->BaseErrorHandler($e);
|
||||||
|
}
|
||||||
|
catch(NotImplementedError $e){
|
||||||
|
$this->app->getErrorInstance()->NotImplementedHandler($e);
|
||||||
|
}
|
||||||
|
catch(Exception $e){
|
||||||
|
$this->app->getErrorInstance()->OtherException($e);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -126,76 +235,400 @@ class compute
|
||||||
*/
|
*/
|
||||||
public function getImage()
|
public function getImage()
|
||||||
{
|
{
|
||||||
$imageId = $this->app->getPostParam("imageId");
|
try{
|
||||||
$opt = array('id' => $imageId);
|
$imageId = $this->app->getPostParam("imageId");
|
||||||
$image = $this->libClass->getImage($opt);
|
if(!isset($serverId)){
|
||||||
$image->retrieve();
|
$this->app->setOutput("Error", "Image ID is missing, son!");
|
||||||
$this->app->setOutput("MyImage", $image);
|
return;
|
||||||
|
}
|
||||||
|
$opt = array('id' => $imageId);
|
||||||
|
$image = $this->libClass->getImage($opt);
|
||||||
|
$image->retrieve();
|
||||||
|
$this->app->setOutput("MyImage", $image);
|
||||||
|
}
|
||||||
|
catch(BadResponseError $e){
|
||||||
|
$this->app->getErrorInstance()->BadResponseHandler($e);
|
||||||
|
}
|
||||||
|
catch(UserInputError $e){
|
||||||
|
$this->app->getErrorInstance()->UserInputHandler($e);
|
||||||
|
}
|
||||||
|
catch(BaseError $e){
|
||||||
|
$this->app->getErrorInstance()->BaseErrorHandler($e);
|
||||||
|
}
|
||||||
|
catch(NotImplementedError $e){
|
||||||
|
$this->app->getErrorInstance()->NotImplementedHandler($e);
|
||||||
|
}
|
||||||
|
catch(Exception $e){
|
||||||
|
$this->app->getErrorInstance()->OtherException($e);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* working on tests
|
/**
|
||||||
|
* Create server.
|
||||||
public function update()
|
* @return array
|
||||||
|
*/
|
||||||
|
public function createServer()
|
||||||
{
|
{
|
||||||
$image = $this->app->getServer(array $options = []);
|
try{
|
||||||
|
$name = $this->app->getPostParam("name");
|
||||||
|
$imageId = $this->app->getPostParam("imageId");
|
||||||
|
$flavorId = $this->app->getPostParam("flavorId");
|
||||||
|
if(!isset($name) || !isset($imageId) || !isset($flavorId)){
|
||||||
|
$this->app->setOutput("Error", "No, we don't let you create a server without a name OR image ID OR flavor ID.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$opt = array('name' => $name, 'imageId' => $imageId, 'flavorId' => $flavorId);
|
||||||
|
$server = $this->libClass->createServer($opt);
|
||||||
|
}
|
||||||
|
catch(BadResponseError $e){
|
||||||
|
$this->app->getErrorInstance()->BadResponseHandler($e);
|
||||||
|
}
|
||||||
|
catch(UserInputError $e){
|
||||||
|
$this->app->getErrorInstance()->UserInputHandler($e);
|
||||||
|
}
|
||||||
|
catch(BaseError $e){
|
||||||
|
$this->app->getErrorInstance()->BaseErrorHandler($e);
|
||||||
|
}
|
||||||
|
catch(NotImplementedError $e){
|
||||||
|
$this->app->getErrorInstance()->NotImplementedHandler($e);
|
||||||
|
}
|
||||||
|
catch(Exception $e){
|
||||||
|
$this->app->getErrorInstance()->OtherException($e);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
public function delete()
|
|
||||||
|
/**
|
||||||
|
* update a server
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function updateServer()
|
||||||
{
|
{
|
||||||
//TODO
|
try{
|
||||||
|
$serverId = $this->app->getPostParam("serverId");
|
||||||
|
$newName = $this->app->getPostParam("newName");
|
||||||
|
$newIpv4 = $this->app->getPostParam("newIpv4");
|
||||||
|
$newIpv6 = $this->app->getPostParam("newIpv6");
|
||||||
|
if(!isset($serverId)|| !(isset($newName) || isset($newIpv4) || isset($newIpv6)) ){
|
||||||
|
$this->app->setOutput("Error", "You'll have to provide server ID and the new attribute(IP(v4/v6)/Name) you desire to update!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$opt = array('id' => $serverId);
|
||||||
|
$server = $this->libClass->getServer($opt);
|
||||||
|
if (isset($newName)){
|
||||||
|
if(isset($newIpv4)){
|
||||||
|
if(isset($newIpv6)){
|
||||||
|
$attr = array('name' => $newName, 'accessIPv4' => $newIPv4, 'accessIPv6' => $newIpv6);
|
||||||
|
}
|
||||||
|
else $attr = array('name' => $newName, 'accessIPv4' => $newIPv4);
|
||||||
|
}
|
||||||
|
else $attr = array('name' => $newName);
|
||||||
|
}
|
||||||
|
$server->update($attr);
|
||||||
|
$this->app->setOutput("Success", $serverId." has been updated successfully.");
|
||||||
|
}
|
||||||
|
catch(BadResponseError $e){
|
||||||
|
$this->app->getErrorInstance()->BadResponseHandler($e);
|
||||||
|
}
|
||||||
|
catch(UserInputError $e){
|
||||||
|
$this->app->getErrorInstance()->UserInputHandler($e);
|
||||||
|
}
|
||||||
|
catch(BaseError $e){
|
||||||
|
$this->app->getErrorInstance()->BaseErrorHandler($e);
|
||||||
|
}
|
||||||
|
catch(NotImplementedError $e){
|
||||||
|
$this->app->getErrorInstance()->NotImplementedHandler($e);
|
||||||
|
}
|
||||||
|
catch(Exception $e){
|
||||||
|
$this->app->getErrorInstance()->OtherException($e);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
public function changePassword($newPassword)
|
/**
|
||||||
|
* Delete a server
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function deleteServer()
|
||||||
{
|
{
|
||||||
//TODO
|
try{
|
||||||
|
$serverId = $this->app->getPostParam("serverId");
|
||||||
|
if(!isset($serverId)){
|
||||||
|
$this->app->setOutput("Error", "Server ID is missing, son!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$opt = array('id' => $serverId);
|
||||||
|
$server = $this->libClass->getServer($opt);
|
||||||
|
$server->delete();
|
||||||
|
$this->app->setOutput("Success", $serverId." has been deleted successfully.");
|
||||||
|
}
|
||||||
|
catch(BadResponseError $e){
|
||||||
|
$this->app->getErrorInstance()->BadResponseHandler($e);
|
||||||
|
}
|
||||||
|
catch(UserInputError $e){
|
||||||
|
$this->app->getErrorInstance()->UserInputHandler($e);
|
||||||
|
}
|
||||||
|
catch(BaseError $e){
|
||||||
|
$this->app->getErrorInstance()->BaseErrorHandler($e);
|
||||||
|
}
|
||||||
|
catch(NotImplementedError $e){
|
||||||
|
$this->app->getErrorInstance()->NotImplementedHandler($e);
|
||||||
|
}
|
||||||
|
catch(Exception $e){
|
||||||
|
$this->app->getErrorInstance()->OtherException($e);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
public function reboot($type = Enum::REBOOT_SOFT)
|
/**
|
||||||
|
* Change the password of a server
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function changePassword()
|
||||||
{
|
{
|
||||||
//TODO
|
try{
|
||||||
|
$serverId = $this->app->getPostParam("serverId");
|
||||||
|
$password = $this->app->getPostParam("newPassword");
|
||||||
|
if(!isset($serverId) || !isset($password)){
|
||||||
|
$this->app->setOutput("Error", "Server ID or new password missing.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$opt = array('id' => $serverId);
|
||||||
|
$server = $this->libClass->getServer($opt);
|
||||||
|
$server->changePassword($password);
|
||||||
|
$this->app->setOutput("Success", "Password for ".$serverId." has been updated successfully.");
|
||||||
|
}
|
||||||
|
catch(BadResponseError $e){
|
||||||
|
$this->app->getErrorInstance()->BadResponseHandler($e);
|
||||||
|
}
|
||||||
|
catch(UserInputError $e){
|
||||||
|
$this->app->getErrorInstance()->UserInputHandler($e);
|
||||||
|
}
|
||||||
|
catch(BaseError $e){
|
||||||
|
$this->app->getErrorInstance()->BaseErrorHandler($e);
|
||||||
|
}
|
||||||
|
catch(NotImplementedError $e){
|
||||||
|
$this->app->getErrorInstance()->NotImplementedHandler($e);
|
||||||
|
}
|
||||||
|
catch(Exception $e){
|
||||||
|
$this->app->getErrorInstance()->OtherException($e);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
public function rebuild(array $options)
|
/**
|
||||||
|
* Reboot a server
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function reboot()
|
||||||
{
|
{
|
||||||
//TODO
|
try{
|
||||||
|
$serverId = $this->app->getPostParam("serverId");
|
||||||
|
if(!isset($serverId)){
|
||||||
|
$this->app->setOutput("Error", "Server ID is missing, son!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$opt = array('id' => $serverId);
|
||||||
|
$server = $this->libClass->getServer($opt);
|
||||||
|
$server->reboot();
|
||||||
|
$this->app->setOutput("Success", $serverId." has been deleted successfully.");
|
||||||
|
}
|
||||||
|
catch(BadResponseError $e){
|
||||||
|
$this->app->getErrorInstance()->BadResponseHandler($e);
|
||||||
|
}
|
||||||
|
catch(UserInputError $e){
|
||||||
|
$this->app->getErrorInstance()->UserInputHandler($e);
|
||||||
|
}
|
||||||
|
catch(BaseError $e){
|
||||||
|
$this->app->getErrorInstance()->BaseErrorHandler($e);
|
||||||
|
}
|
||||||
|
catch(NotImplementedError $e){
|
||||||
|
$this->app->getErrorInstance()->NotImplementedHandler($e);
|
||||||
|
}
|
||||||
|
catch(Exception $e){
|
||||||
|
$this->app->getErrorInstance()->OtherException($e);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
public function resize($flavorId)
|
/**
|
||||||
|
* Rebuild a server
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function rebuild()
|
||||||
{
|
{
|
||||||
//TODO
|
$serverId = $this->app->getPostParam("serverId");
|
||||||
|
$imageId = $this->app->getPostParam("imageId");
|
||||||
|
$newName = $this->app->getPostParam("newName");
|
||||||
|
$adminPass = $this->app->getPostParam("adminPass");
|
||||||
|
if(!isset($serverId)|| !isset($imageId) || isset($newName) || isset($adminPass)) {
|
||||||
|
$this->app->setOutput("Error", "You'll have to provide server ID and the new image, name and admin password!");
|
||||||
|
return;
|
||||||
|
try{
|
||||||
|
$serverId = $this->app->getPostParam("serverId");
|
||||||
|
$imageId = $this->app->getPostParam("imageId");
|
||||||
|
$newName = $this->app->getPostParam("newName");
|
||||||
|
$adminPass = $this->app->getPostParam("adminPass");
|
||||||
|
if(!isset($serverId)|| !isset($imageId) || isset($newName) || isset($adminPass)){
|
||||||
|
$this->app->setOutput("Error", "You'll have to provide server ID and the new image, name and admin password!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$opt = array('id' => $serverId);
|
||||||
|
$server = $this->libClass->getServer($opt);
|
||||||
|
$attr = array('imageId' => $imageId, 'name' => $newName, 'adminPass' => $adminPass);
|
||||||
|
$server->rebuild($attr);
|
||||||
|
$this->app->setOutput("Success", $serverId." has been rebuilt successfully with the new image.");
|
||||||
|
}
|
||||||
|
catch(BadResponseError $e){
|
||||||
|
$this->app->getErrorInstance()->BadResponseHandler($e);
|
||||||
|
}
|
||||||
|
catch(UserInputError $e){
|
||||||
|
$this->app->getErrorInstance()->UserInputHandler($e);
|
||||||
|
}
|
||||||
|
catch(BaseError $e){
|
||||||
|
$this->app->getErrorInstance()->BaseErrorHandler($e);
|
||||||
|
}
|
||||||
|
catch(NotImplementedError $e){
|
||||||
|
$this->app->getErrorInstance()->NotImplementedHandler($e);
|
||||||
|
}
|
||||||
|
catch(Exception $e){
|
||||||
|
$this->app->getErrorInstance()->OtherException($e);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Resize a server
|
||||||
|
* A call to this method has to be followed by either confirmResize or revertResize
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function resize()
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
$serverId = $this->app->getPostParam("serverId");
|
||||||
|
$newFlavorId = $this->app->getPostParam("newFlavorId");
|
||||||
|
if(!isset($serverId)|| !isset($flavorId)){
|
||||||
|
$this->app->setOutput("Error", "You'll have to provide server ID and the new flavor ID!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$opt = array('id' => $serverId);
|
||||||
|
$server = $this->libClass->getServer($opt);
|
||||||
|
$server->resize($newFlavorId);
|
||||||
|
}
|
||||||
|
catch(BadResponseError $e){
|
||||||
|
$this->app->getErrorInstance()->BadResponseHandler($e);
|
||||||
|
}
|
||||||
|
catch(UserInputError $e){
|
||||||
|
$this->app->getErrorInstance()->UserInputHandler($e);
|
||||||
|
}
|
||||||
|
catch(BaseError $e){
|
||||||
|
$this->app->getErrorInstance()->BaseErrorHandler($e);
|
||||||
|
}
|
||||||
|
catch(NotImplementedError $e){
|
||||||
|
$this->app->getErrorInstance()->NotImplementedHandler($e);
|
||||||
|
}
|
||||||
|
catch(Exception $e){
|
||||||
|
$this->app->getErrorInstance()->OtherException($e);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Confirm resize operation on a server
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
public function confirmResize()
|
public function confirmResize()
|
||||||
{
|
{
|
||||||
//TODO
|
try{
|
||||||
|
$serverId = $this->app->getPostParam("serverId");
|
||||||
|
if(!isset($serverId)){
|
||||||
|
$this->app->setOutput("Error", "Server ID is missing!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$opt = array('id' => $serverId);
|
||||||
|
$server = $this->libClass->getServer($opt);
|
||||||
|
$server->confirmResize();
|
||||||
|
$this->app->setOutput("Success", $serverId." has been resized successfully as the new flavor.");
|
||||||
|
}
|
||||||
|
catch(BadResponseError $e){
|
||||||
|
$this->app->getErrorInstance()->BadResponseHandler($e);
|
||||||
|
}
|
||||||
|
catch(UserInputError $e){
|
||||||
|
$this->app->getErrorInstance()->UserInputHandler($e);
|
||||||
|
}
|
||||||
|
catch(BaseError $e){
|
||||||
|
$this->app->getErrorInstance()->BaseErrorHandler($e);
|
||||||
|
}
|
||||||
|
catch(NotImplementedError $e){
|
||||||
|
$this->app->getErrorInstance()->NotImplementedHandler($e);
|
||||||
|
}
|
||||||
|
catch(Exception $e){
|
||||||
|
$this->app->getErrorInstance()->OtherException($e);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Revert resize operation on a server
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
public function revertResize()
|
public function revertResize()
|
||||||
{
|
{
|
||||||
//TODO
|
try{
|
||||||
}
|
$serverId = $this->app->getPostParam("serverId");
|
||||||
public function createImage(array $options)
|
if(!isset($serverId)){
|
||||||
{
|
$this->app->setOutput("Error", "Server ID is missing!");
|
||||||
//TODO
|
return;
|
||||||
|
}
|
||||||
|
$opt = array('id' => $serverId);
|
||||||
|
$server = $this->libClass->getServer($opt);
|
||||||
|
$server->revertResize();
|
||||||
|
$this->app->setOutput("Success", $serverId." : resize operation has been reverted to the old flavor.");
|
||||||
|
}
|
||||||
|
catch(BadResponseError $e){
|
||||||
|
$this->app->getErrorInstance()->BadResponseHandler($e);
|
||||||
|
}
|
||||||
|
catch(UserInputError $e){
|
||||||
|
$this->app->getErrorInstance()->UserInputHandler($e);
|
||||||
|
}
|
||||||
|
catch(BaseError $e){
|
||||||
|
$this->app->getErrorInstance()->BaseErrorHandler($e);
|
||||||
|
}
|
||||||
|
catch(NotImplementedError $e){
|
||||||
|
$this->app->getErrorInstance()->NotImplementedHandler($e);
|
||||||
|
}
|
||||||
|
catch(Exception $e){
|
||||||
|
$this->app->getErrorInstance()->OtherException($e);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* List private and public addresses of a server
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
public function listAddresses(array $options = [])
|
public function listAddresses(array $options = [])
|
||||||
{
|
{
|
||||||
//TODO
|
try{
|
||||||
|
$serverId = $this->app->getPostParam("serverId");
|
||||||
|
if(!isset($serverId)){
|
||||||
|
$this->app->setOutput("Error", "Server ID is missing!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$opt = array('id' => $serverId);
|
||||||
|
$server = $this->libClass->getServer($opt);
|
||||||
|
$addresses = $server->listAddresses();
|
||||||
|
$this->app->setOutput("Addresses", $addresses);
|
||||||
|
}
|
||||||
|
catch(BadResponseError $e){
|
||||||
|
$this->app->getErrorInstance()->BadResponseHandler($e);
|
||||||
|
}
|
||||||
|
catch(UserInputError $e){
|
||||||
|
$this->app->getErrorInstance()->UserInputHandler($e);
|
||||||
|
}
|
||||||
|
catch(BaseError $e){
|
||||||
|
$this->app->getErrorInstance()->BaseErrorHandler($e);
|
||||||
|
}
|
||||||
|
catch(NotImplementedError $e){
|
||||||
|
$this->app->getErrorInstance()->NotImplementedHandler($e);
|
||||||
|
}
|
||||||
|
catch(Exception $e){
|
||||||
|
$this->app->getErrorInstance()->OtherException($e);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
public function getMetadata()
|
|
||||||
{
|
|
||||||
//TODO
|
|
||||||
}
|
|
||||||
public function resetMetadata(array $metadata)
|
|
||||||
{
|
|
||||||
//TODO
|
|
||||||
}
|
|
||||||
public function mergeMetadata(array $metadata)
|
|
||||||
{
|
|
||||||
//TODO
|
|
||||||
}
|
|
||||||
public function getMetadataItem($key)
|
|
||||||
{
|
|
||||||
//TODO
|
|
||||||
}
|
|
||||||
public function deleteMetadataItem($key)
|
|
||||||
{
|
|
||||||
//TODO
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use OpenStack\Common\Error\BadResponseError;
|
use OpenCloud\Common\Error\BadResponseError;
|
||||||
use OpenStack\Common\Error\BaseError;
|
use OpenCloud\Common\Error\BaseError;
|
||||||
use OpenStack\Common\Error\NotImplementedError;
|
use OpenCloud\Common\Error\NotImplementedError;
|
||||||
use OpenStack\Common\Error\UserInputError;
|
use OpenCloud\Common\Error\UserInputError;
|
||||||
|
|
||||||
|
|
||||||
Class errorManagement{
|
Class errorManagement{
|
||||||
|
@ -32,8 +32,12 @@ Class errorManagement{
|
||||||
public function UserInputHandler($error){
|
public function UserInputHandler($error){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function OtherException($error){
|
||||||
|
$this->app->setOutput("Error", $error->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
File diff suppressed because it is too large
Load diff
860
server/core/Image.php
Normal file → Executable file
860
server/core/Image.php
Normal file → Executable file
File diff suppressed because it is too large
Load diff
|
@ -1,12 +1,12 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use GuzzleHttp\Client;
|
use GuzzleHttp\Client;
|
||||||
use OpenStack\Common\Transport\HandlerStack;
|
use OpenCloud\Common\Transport\HandlerStack;
|
||||||
use OpenStack\Common\Transport\Middleware;
|
use OpenCloud\Common\Transport\Middleware;
|
||||||
use OpenStack\Identity\v3\Service;
|
use OpenStack\Identity\v3\Service;
|
||||||
use OpenStack\Identity\v3\Api;
|
use OpenStack\Identity\v3\Api;
|
||||||
use OpenStack\Common\Auth\Token;
|
use OpenCloud\Common\Auth\Token;
|
||||||
use OpenStack\Common\Transport\Utils;
|
use OpenCloud\Common\Transport\Utils;
|
||||||
use OpenStack\Identity\v3\Models;
|
use OpenStack\Identity\v3\Models;
|
||||||
|
|
||||||
class genTokenOptions
|
class genTokenOptions
|
||||||
|
@ -75,6 +75,12 @@ class genTokenOptions
|
||||||
$this->optionsGlobal['Identity'] = $options;
|
$this->optionsGlobal['Identity'] = $options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function revokeIdentityToken(){
|
||||||
|
$token = $this->unserializeToken($this->backup['Identity']['token']);
|
||||||
|
$this->optionsGlobal['Common']['identityService']->revokeToken($token->id);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public function loadIdentityBackup($opt){
|
public function loadIdentityBackup($opt){
|
||||||
$options = $this->optionsGlobal['Common'];
|
$options = $this->optionsGlobal['Common'];
|
||||||
$options['catalogName'] = 'false';
|
$options['catalogName'] = 'false';
|
||||||
|
@ -123,6 +129,12 @@ class genTokenOptions
|
||||||
$this->optionsGlobal['Image'] = $options;
|
$this->optionsGlobal['Image'] = $options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function revokeImageToken(){
|
||||||
|
$token = $this->unserializeToken($this->backup['Image']['token']);
|
||||||
|
$this->optionsGlobal['Common']['identityService']->revokeToken($token->id);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public function loadImageBackup($opt){
|
public function loadImageBackup($opt){
|
||||||
$options = $this->optionsGlobal['Common'];
|
$options = $this->optionsGlobal['Common'];
|
||||||
$options['catalogName'] = 'glance';
|
$options['catalogName'] = 'glance';
|
||||||
|
@ -157,7 +169,7 @@ class genTokenOptions
|
||||||
|
|
||||||
$stack = HandlerStack::create();
|
$stack = HandlerStack::create();
|
||||||
|
|
||||||
$stack->push(Middleware::authHandler($options['authHandler'], $token));
|
$stack->push(Middleware::authHandler($options['authHandler'], $token));
|
||||||
|
|
||||||
$this->addDebugMiddleware($options, $stack);
|
$this->addDebugMiddleware($options, $stack);
|
||||||
|
|
||||||
|
@ -170,6 +182,12 @@ class genTokenOptions
|
||||||
$this->optionsGlobal['Network'] = $options;
|
$this->optionsGlobal['Network'] = $options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function revokeNetworkToken(){
|
||||||
|
$token = $this->unserializeToken($this->backup['Network']['token']);
|
||||||
|
$this->optionsGlobal['Common']['identityService']->revokeToken($token->id);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public function loadNetworkBackup($opt){
|
public function loadNetworkBackup($opt){
|
||||||
$options = $this->optionsGlobal['Common'];
|
$options = $this->optionsGlobal['Common'];
|
||||||
$options['catalogName'] = 'neutron';
|
$options['catalogName'] = 'neutron';
|
||||||
|
@ -217,6 +235,12 @@ class genTokenOptions
|
||||||
$this->optionsGlobal['Compute'] = $options;
|
$this->optionsGlobal['Compute'] = $options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function revokeComputeToken(){
|
||||||
|
$token = $this->unserializeToken($this->backup['Compute']['token']);
|
||||||
|
$this->optionsGlobal['Common']['identityService']->revokeToken($token->id);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public function loadComputeBackup($opt){
|
public function loadComputeBackup($opt){
|
||||||
|
|
||||||
$options = $this->optionsGlobal['Common'];
|
$options = $this->optionsGlobal['Common'];
|
||||||
|
@ -245,7 +269,7 @@ class genTokenOptions
|
||||||
private function saveBackup($name, $data){
|
private function saveBackup($name, $data){
|
||||||
$token = $this->serializeToken($data["token"]);
|
$token = $this->serializeToken($data["token"]);
|
||||||
$path = "core/LibOverride/projectTokenData/".$token['saved']["project"]["name"];
|
$path = "core/LibOverride/projectTokenData/".$token['saved']["project"]["name"];
|
||||||
error_log(print_r($path, true), 0);
|
//error_log(print_r($path, true), 0);
|
||||||
file_put_contents("core/LibOverride/projectTokenData/".$token['saved']["project"]["name"], serialize($token['saved']));
|
file_put_contents("core/LibOverride/projectTokenData/".$token['saved']["project"]["name"], serialize($token['saved']));
|
||||||
$this->backup["roles"] = $token["roles"];
|
$this->backup["roles"] = $token["roles"];
|
||||||
$this->backup["project"] = $token['saved']["project"]["name"];
|
$this->backup["project"] = $token['saved']["project"]["name"];
|
||||||
|
|
70
server/index.php
Normal file → Executable file
70
server/index.php
Normal file → Executable file
|
@ -6,7 +6,7 @@
|
||||||
if(isset($_POST["task"]) && isset($_POST["action"])){
|
if(isset($_POST["task"]) && isset($_POST["action"])){
|
||||||
$task = $_POST["task"];
|
$task = $_POST["task"];
|
||||||
$action = $_POST["action"];
|
$action = $_POST["action"];
|
||||||
}else if(isset($_POST["task"]) && $_POST["task"] == "Authenticate"){
|
}else if(isset($_POST["task"]) && $_POST["task"] == "Authenticate" || $_POST["task"] == "Deauthenticate"){
|
||||||
$task = $_POST["task"];
|
$task = $_POST["task"];
|
||||||
}else{
|
}else{
|
||||||
//Gestion Erreur
|
//Gestion Erreur
|
||||||
|
@ -17,36 +17,44 @@
|
||||||
$App->authenticate();
|
$App->authenticate();
|
||||||
$App->show();
|
$App->show();
|
||||||
|
|
||||||
|
}else if($task == "Deauthenticate"){
|
||||||
|
|
||||||
|
$App->deauthenticate();
|
||||||
|
$App->show();
|
||||||
|
|
||||||
|
}else{
|
||||||
|
switch($task)
|
||||||
|
{
|
||||||
|
case "identity":
|
||||||
|
include_once("core/Identity.php");
|
||||||
|
$identityObject = new identity($App);
|
||||||
|
$identityObject->action($action);
|
||||||
|
$App->show();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "network":
|
||||||
|
include_once("core/Network.php");
|
||||||
|
$networkObject = new network($App);
|
||||||
|
$networkObject->action($action);
|
||||||
|
$App->show();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "image":
|
||||||
|
include_once("core/Image.php");
|
||||||
|
$imageObject = new image($App);
|
||||||
|
$imageObject->action($action);
|
||||||
|
$App->show();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "compute":
|
||||||
|
include_once("core/Compute.php");
|
||||||
|
$computeObject = new compute($App);
|
||||||
|
$computeObject->action($action);
|
||||||
|
$App->show();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch($task)
|
|
||||||
{
|
|
||||||
case "identity":
|
|
||||||
include_once("core/Identity.php");
|
|
||||||
$identityObject = new identity($App);
|
|
||||||
$identityObject->action($action);
|
|
||||||
$App->show();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "network":
|
|
||||||
include_once("core/Network.php");
|
|
||||||
$networkObject = new network($App);
|
|
||||||
$networkObject->action($action);
|
|
||||||
$App->show();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "image":
|
|
||||||
include_once("core/Image.php");
|
|
||||||
$imageObject = new image($App);
|
|
||||||
$imageObject->action($action);
|
|
||||||
$App->show();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "compute":
|
|
||||||
include_once("core/Compute.php");
|
|
||||||
$computeObject = new compute($App);
|
|
||||||
$computeObject->action($action);
|
|
||||||
$App->show();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
5
server/vendor/composer/autoload_psr4.php
vendored
5
server/vendor/composer/autoload_psr4.php
vendored
|
@ -7,9 +7,10 @@ $baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'),
|
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'),
|
||||||
'OpenStack\\Test\\' => array($vendorDir . '/php-opencloud/openstack/tests/unit'),
|
|
||||||
'OpenStack\\Integration\\' => array($vendorDir . '/php-opencloud/openstack/tests/integration'),
|
|
||||||
'OpenStack\\' => array($vendorDir . '/php-opencloud/openstack/src'),
|
'OpenStack\\' => array($vendorDir . '/php-opencloud/openstack/src'),
|
||||||
|
'OpenCloud\\Test\\' => array($vendorDir . '/php-opencloud/common/tests/unit'),
|
||||||
|
'OpenCloud\\Integration\\' => array($vendorDir . '/php-opencloud/common/tests/integration'),
|
||||||
|
'OpenCloud\\' => array($vendorDir . '/php-opencloud/common/src'),
|
||||||
'JsonSchema\\' => array($vendorDir . '/justinrainbow/json-schema/src/JsonSchema'),
|
'JsonSchema\\' => array($vendorDir . '/justinrainbow/json-schema/src/JsonSchema'),
|
||||||
'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'),
|
'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'),
|
||||||
'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'),
|
'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'),
|
||||||
|
|
260
server/vendor/composer/installed.json
vendored
260
server/vendor/composer/installed.json
vendored
|
@ -1,57 +1,4 @@
|
||||||
[
|
[
|
||||||
{
|
|
||||||
"name": "guzzlehttp/promises",
|
|
||||||
"version": "1.0.3",
|
|
||||||
"version_normalized": "1.0.3.0",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/guzzle/promises.git",
|
|
||||||
"reference": "b1e1c0d55f8083c71eda2c28c12a228d708294ea"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/guzzle/promises/zipball/b1e1c0d55f8083c71eda2c28c12a228d708294ea",
|
|
||||||
"reference": "b1e1c0d55f8083c71eda2c28c12a228d708294ea",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=5.5.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"phpunit/phpunit": "~4.0"
|
|
||||||
},
|
|
||||||
"time": "2015-10-15 22:28:00",
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "1.0-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"installation-source": "dist",
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"GuzzleHttp\\Promise\\": "src/"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"src/functions_include.php"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Michael Dowling",
|
|
||||||
"email": "mtdowling@gmail.com",
|
|
||||||
"homepage": "https://github.com/mtdowling"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Guzzle promises library",
|
|
||||||
"keywords": [
|
|
||||||
"promise"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "psr/http-message",
|
"name": "psr/http-message",
|
||||||
"version": "1.0",
|
"version": "1.0",
|
||||||
|
@ -167,54 +114,6 @@
|
||||||
"web service"
|
"web service"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "php-opencloud/openstack",
|
|
||||||
"version": "dev-master",
|
|
||||||
"version_normalized": "9999999-dev",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/php-opencloud/openstack.git",
|
|
||||||
"reference": "15aca73f423166c7ef8337ba08615c103c66e931"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/php-opencloud/openstack/zipball/15aca73f423166c7ef8337ba08615c103c66e931",
|
|
||||||
"reference": "15aca73f423166c7ef8337ba08615c103c66e931",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"guzzlehttp/guzzle": "~6.1",
|
|
||||||
"justinrainbow/json-schema": "~1.3",
|
|
||||||
"php": ">=5.6"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"fabpot/php-cs-fixer": "~1.0",
|
|
||||||
"jakub-onderka/php-parallel-lint": "0.*",
|
|
||||||
"phpspec/prophecy-phpunit": "~1.0",
|
|
||||||
"phpunit/phpunit": "~4.0",
|
|
||||||
"psr/log": "~1.0",
|
|
||||||
"sami/sami": "dev-master",
|
|
||||||
"satooshi/php-coveralls": "~1.0"
|
|
||||||
},
|
|
||||||
"time": "2016-01-25 10:35:10",
|
|
||||||
"type": "library",
|
|
||||||
"installation-source": "source",
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"OpenStack\\": "src/",
|
|
||||||
"OpenStack\\Test\\": "tests/unit/",
|
|
||||||
"OpenStack\\Integration\\": "tests/integration/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Jamie Hannaford",
|
|
||||||
"email": "jamie.hannaford@rackspace.com",
|
|
||||||
"homepage": "https://github.com/jamiehannaford"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "justinrainbow/json-schema",
|
"name": "justinrainbow/json-schema",
|
||||||
"version": "1.6.1",
|
"version": "1.6.1",
|
||||||
|
@ -284,18 +183,118 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "guzzlehttp/psr7",
|
"name": "php-opencloud/common",
|
||||||
"version": "1.2.2",
|
"version": "dev-master",
|
||||||
"version_normalized": "1.2.2.0",
|
"version_normalized": "9999999-dev",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/guzzle/psr7.git",
|
"url": "https://github.com/php-opencloud/common.git",
|
||||||
"reference": "f5d04bdd2881ac89abde1fb78cc234bce24327bb"
|
"reference": "fd027b817c3dd8f83b0c8d9fb1df34ebf25f8c62"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/guzzle/psr7/zipball/f5d04bdd2881ac89abde1fb78cc234bce24327bb",
|
"url": "https://api.github.com/repos/php-opencloud/common/zipball/fd027b817c3dd8f83b0c8d9fb1df34ebf25f8c62",
|
||||||
"reference": "f5d04bdd2881ac89abde1fb78cc234bce24327bb",
|
"reference": "fd027b817c3dd8f83b0c8d9fb1df34ebf25f8c62",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"guzzlehttp/guzzle": "~6.1",
|
||||||
|
"justinrainbow/json-schema": "~1.3",
|
||||||
|
"php": "~7.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"fabpot/php-cs-fixer": "~1.0",
|
||||||
|
"jakub-onderka/php-parallel-lint": "0.*",
|
||||||
|
"phpunit/phpunit": "~4.0",
|
||||||
|
"psr/log": "~1.0",
|
||||||
|
"sami/sami": "dev-master",
|
||||||
|
"satooshi/php-coveralls": "~1.0"
|
||||||
|
},
|
||||||
|
"time": "2016-03-08 12:56:34",
|
||||||
|
"type": "library",
|
||||||
|
"installation-source": "source",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"OpenCloud\\": "src/",
|
||||||
|
"OpenCloud\\Test\\": "tests/unit/",
|
||||||
|
"OpenCloud\\Integration\\": "tests/integration/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Jamie Hannaford",
|
||||||
|
"email": "jamie.hannaford@rackspace.com",
|
||||||
|
"homepage": "https://github.com/jamiehannaford"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "guzzlehttp/promises",
|
||||||
|
"version": "1.1.0",
|
||||||
|
"version_normalized": "1.1.0.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/guzzle/promises.git",
|
||||||
|
"reference": "bb9024c526b22f3fe6ae55a561fd70653d470aa8"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/guzzle/promises/zipball/bb9024c526b22f3fe6ae55a561fd70653d470aa8",
|
||||||
|
"reference": "bb9024c526b22f3fe6ae55a561fd70653d470aa8",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.5.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "~4.0"
|
||||||
|
},
|
||||||
|
"time": "2016-03-08 01:15:46",
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.0-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"installation-source": "dist",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"GuzzleHttp\\Promise\\": "src/"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"src/functions_include.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Michael Dowling",
|
||||||
|
"email": "mtdowling@gmail.com",
|
||||||
|
"homepage": "https://github.com/mtdowling"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Guzzle promises library",
|
||||||
|
"keywords": [
|
||||||
|
"promise"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "guzzlehttp/psr7",
|
||||||
|
"version": "1.2.3",
|
||||||
|
"version_normalized": "1.2.3.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/guzzle/psr7.git",
|
||||||
|
"reference": "2e89629ff057ebb49492ba08e6995d3a6a80021b"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/guzzle/psr7/zipball/2e89629ff057ebb49492ba08e6995d3a6a80021b",
|
||||||
|
"reference": "2e89629ff057ebb49492ba08e6995d3a6a80021b",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -308,7 +307,7 @@
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "~4.0"
|
"phpunit/phpunit": "~4.0"
|
||||||
},
|
},
|
||||||
"time": "2016-01-23 01:23:02",
|
"time": "2016-02-18 21:54:00",
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
|
@ -342,5 +341,48 @@
|
||||||
"stream",
|
"stream",
|
||||||
"uri"
|
"uri"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "php-opencloud/openstack",
|
||||||
|
"version": "dev-master",
|
||||||
|
"version_normalized": "9999999-dev",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/php-opencloud/openstack.git",
|
||||||
|
"reference": "f2ee77024843659d970817a9e7055bb40a3724f9"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/php-opencloud/openstack/zipball/f2ee77024843659d970817a9e7055bb40a3724f9",
|
||||||
|
"reference": "f2ee77024843659d970817a9e7055bb40a3724f9",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php-opencloud/common": "dev-master"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"fabpot/php-cs-fixer": "~1.0",
|
||||||
|
"jakub-onderka/php-parallel-lint": "0.*",
|
||||||
|
"phpunit/phpunit": "~4.0",
|
||||||
|
"psr/log": "~1.0",
|
||||||
|
"sami/sami": "dev-master",
|
||||||
|
"satooshi/php-coveralls": "~1.0"
|
||||||
|
},
|
||||||
|
"time": "2016-03-08 14:37:14",
|
||||||
|
"type": "library",
|
||||||
|
"installation-source": "source",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"OpenStack\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Jamie Hannaford",
|
||||||
|
"email": "jamie.hannaford@rackspace.com",
|
||||||
|
"homepage": "https://github.com/jamiehannaford"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
# CHANGELOG
|
# CHANGELOG
|
||||||
|
|
||||||
|
## 1.1.0 - 2016-03-07
|
||||||
|
|
||||||
|
* Update EachPromise to prevent recurring on a iterator when advancing, as this
|
||||||
|
could trigger fatal generator errors.
|
||||||
|
* Update Promise to allow recursive waiting without unwrapping exceptions.
|
||||||
|
|
||||||
## 1.0.3 - 2015-10-15
|
## 1.0.3 - 2015-10-15
|
||||||
|
|
||||||
* Update EachPromise to immediately resolve when the underlying promise iterator
|
* Update EachPromise to immediately resolve when the underlying promise iterator
|
||||||
|
|
|
@ -24,6 +24,9 @@ class EachPromise implements PromisorInterface
|
||||||
/** @var Promise */
|
/** @var Promise */
|
||||||
private $aggregate;
|
private $aggregate;
|
||||||
|
|
||||||
|
/** @var bool */
|
||||||
|
private $mutex;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration hash can include the following key value pairs:
|
* Configuration hash can include the following key value pairs:
|
||||||
*
|
*
|
||||||
|
@ -81,6 +84,7 @@ class EachPromise implements PromisorInterface
|
||||||
|
|
||||||
private function createPromise()
|
private function createPromise()
|
||||||
{
|
{
|
||||||
|
$this->mutex = false;
|
||||||
$this->aggregate = new Promise(function () {
|
$this->aggregate = new Promise(function () {
|
||||||
reset($this->pending);
|
reset($this->pending);
|
||||||
if (empty($this->pending) && !$this->iterable->valid()) {
|
if (empty($this->pending) && !$this->iterable->valid()) {
|
||||||
|
@ -169,11 +173,21 @@ class EachPromise implements PromisorInterface
|
||||||
|
|
||||||
private function advanceIterator()
|
private function advanceIterator()
|
||||||
{
|
{
|
||||||
|
// Place a lock on the iterator so that we ensure to not recurse,
|
||||||
|
// preventing fatal generator errors.
|
||||||
|
if ($this->mutex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->mutex = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$this->iterable->next();
|
$this->iterable->next();
|
||||||
|
$this->mutex = false;
|
||||||
return true;
|
return true;
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->aggregate->reject($e);
|
$this->aggregate->reject($e);
|
||||||
|
$this->mutex = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -186,9 +200,11 @@ class EachPromise implements PromisorInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
unset($this->pending[$idx]);
|
unset($this->pending[$idx]);
|
||||||
$this->advanceIterator();
|
|
||||||
|
|
||||||
if (!$this->checkIfFinished()) {
|
// Only refill pending promises if we are not locked, preventing the
|
||||||
|
// EachPromise to recursively invoke the provided iterator, which
|
||||||
|
// cause a fatal error: "Cannot resume an already running generator"
|
||||||
|
if ($this->advanceIterator() && !$this->checkIfFinished()) {
|
||||||
// Add more pending promises if possible.
|
// Add more pending promises if possible.
|
||||||
$this->refillPending();
|
$this->refillPending();
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,17 +61,19 @@ class Promise implements PromiseInterface
|
||||||
{
|
{
|
||||||
$this->waitIfPending();
|
$this->waitIfPending();
|
||||||
|
|
||||||
if (!$unwrap) {
|
$inner = $this->result instanceof PromiseInterface
|
||||||
return null;
|
? $this->result->wait($unwrap)
|
||||||
}
|
: $this->result;
|
||||||
|
|
||||||
if ($this->result instanceof PromiseInterface) {
|
if ($unwrap) {
|
||||||
return $this->result->wait($unwrap);
|
if ($this->result instanceof PromiseInterface
|
||||||
} elseif ($this->state === self::FULFILLED) {
|
|| $this->state === self::FULFILLED
|
||||||
return $this->result;
|
) {
|
||||||
} else {
|
return $inner;
|
||||||
// It's rejected so "unwrap" and throw an exception.
|
} else {
|
||||||
throw exception_for($this->result);
|
// It's rejected so "unwrap" and throw an exception.
|
||||||
|
throw exception_for($inner);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,11 +259,10 @@ class Promise implements PromiseInterface
|
||||||
$this->waitList = null;
|
$this->waitList = null;
|
||||||
|
|
||||||
foreach ($waitList as $result) {
|
foreach ($waitList as $result) {
|
||||||
descend:
|
|
||||||
$result->waitIfPending();
|
$result->waitIfPending();
|
||||||
if ($result->result instanceof Promise) {
|
while ($result->result instanceof Promise) {
|
||||||
$result = $result->result;
|
$result = $result->result;
|
||||||
goto descend;
|
$result->waitIfPending();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,7 @@ class TaskQueue
|
||||||
*/
|
*/
|
||||||
public function run()
|
public function run()
|
||||||
{
|
{
|
||||||
|
/** @var callable $task */
|
||||||
while ($task = array_shift($this->queue)) {
|
while ($task = array_shift($this->queue)) {
|
||||||
$task();
|
$task();
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,9 +146,9 @@ function inspect(PromiseInterface $promise)
|
||||||
'value' => $promise->wait()
|
'value' => $promise->wait()
|
||||||
];
|
];
|
||||||
} catch (RejectionException $e) {
|
} catch (RejectionException $e) {
|
||||||
return ['state' => 'rejected', 'reason' => $e->getReason()];
|
return ['state' => PromiseInterface::REJECTED, 'reason' => $e->getReason()];
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
return ['state' => 'rejected', 'reason' => $e];
|
return ['state' => PromiseInterface::REJECTED, 'reason' => $e];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,10 +304,10 @@ function settle($promises)
|
||||||
return each(
|
return each(
|
||||||
$promises,
|
$promises,
|
||||||
function ($value, $idx) use (&$results) {
|
function ($value, $idx) use (&$results) {
|
||||||
$results[$idx] = ['state' => 'fulfilled', 'value' => $value];
|
$results[$idx] = ['state' => PromiseInterface::FULFILLED, 'value' => $value];
|
||||||
},
|
},
|
||||||
function ($reason, $idx) use (&$results) {
|
function ($reason, $idx) use (&$results) {
|
||||||
$results[$idx] = ['state' => 'rejected', 'reason' => $reason];
|
$results[$idx] = ['state' => PromiseInterface::REJECTED, 'reason' => $reason];
|
||||||
}
|
}
|
||||||
)->then(function () use (&$results) {
|
)->then(function () use (&$results) {
|
||||||
ksort($results);
|
ksort($results);
|
||||||
|
|
|
@ -39,8 +39,8 @@ class EachPromiseTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
public function testIsWaitable()
|
public function testIsWaitable()
|
||||||
{
|
{
|
||||||
$a = new Promise(function () use (&$a) { $a->resolve('a'); });
|
$a = $this->createSelfResolvingPromise('a');
|
||||||
$b = new Promise(function () use (&$b) { $b->resolve('b'); });
|
$b = $this->createSelfResolvingPromise('b');
|
||||||
$called = [];
|
$called = [];
|
||||||
$each = new EachPromise([$a, $b], [
|
$each = new EachPromise([$a, $b], [
|
||||||
'fulfilled' => function ($value) use (&$called) { $called[] = $value; }
|
'fulfilled' => function ($value) use (&$called) { $called[] = $value; }
|
||||||
|
@ -54,7 +54,7 @@ class EachPromiseTest extends \PHPUnit_Framework_TestCase
|
||||||
public function testCanResolveBeforeConsumingAll()
|
public function testCanResolveBeforeConsumingAll()
|
||||||
{
|
{
|
||||||
$called = 0;
|
$called = 0;
|
||||||
$a = new Promise(function () use (&$a) { $a->resolve('a'); });
|
$a = $this->createSelfResolvingPromise('a');
|
||||||
$b = new Promise(function () { $this->fail(); });
|
$b = new Promise(function () { $this->fail(); });
|
||||||
$each = new EachPromise([$a, $b], [
|
$each = new EachPromise([$a, $b], [
|
||||||
'fulfilled' => function ($value, $idx, Promise $aggregate) use (&$called) {
|
'fulfilled' => function ($value, $idx, Promise $aggregate) use (&$called) {
|
||||||
|
@ -291,4 +291,46 @@ class EachPromiseTest extends \PHPUnit_Framework_TestCase
|
||||||
}
|
}
|
||||||
$this->assertEquals(range(0, 9), $results);
|
$this->assertEquals(range(0, 9), $results);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function createSelfResolvingPromise($value)
|
||||||
|
{
|
||||||
|
$p = new Promise(function () use (&$p, $value) {
|
||||||
|
$p->resolve($value);
|
||||||
|
});
|
||||||
|
|
||||||
|
return $p;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMutexPreventsGeneratorRecursion()
|
||||||
|
{
|
||||||
|
$results = $promises = [];
|
||||||
|
for ($i = 0; $i < 20; $i++) {
|
||||||
|
$p = $this->createSelfResolvingPromise($i);
|
||||||
|
$pending[] = $p;
|
||||||
|
$promises[] = $p;
|
||||||
|
}
|
||||||
|
|
||||||
|
$iter = function () use (&$promises, &$pending) {
|
||||||
|
foreach ($promises as $promise) {
|
||||||
|
// Resolve a promises, which will trigger the then() function,
|
||||||
|
// which would cause the EachPromise to try to add more
|
||||||
|
// promises to the queue. Without a lock, this would trigger
|
||||||
|
// a "Cannot resume an already running generator" fatal error.
|
||||||
|
if ($p = array_pop($pending)) {
|
||||||
|
$p->wait();
|
||||||
|
}
|
||||||
|
yield $promise;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$each = new EachPromise($iter(), [
|
||||||
|
'concurrency' => 5,
|
||||||
|
'fulfilled' => function ($r) use (&$results, &$pending) {
|
||||||
|
$results[] = $r;
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
$each->promise()->wait();
|
||||||
|
$this->assertCount(20, $results);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,6 +172,18 @@ class PromiseTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->assertEquals('Whoop', $p->wait());
|
$this->assertEquals('Whoop', $p->wait());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testWaitsOnAPromiseChainEvenWhenNotUnwrapped()
|
||||||
|
{
|
||||||
|
$p2 = new Promise(function () use (&$p2) {
|
||||||
|
$p2->reject('Fail');
|
||||||
|
});
|
||||||
|
$p = new Promise(function () use ($p2, &$p) {
|
||||||
|
$p->resolve($p2);
|
||||||
|
});
|
||||||
|
$p->wait(false);
|
||||||
|
$this->assertSame(Promise::REJECTED, $p2->getState());
|
||||||
|
}
|
||||||
|
|
||||||
public function testCannotCancelNonPending()
|
public function testCannotCancelNonPending()
|
||||||
{
|
{
|
||||||
$p = new Promise();
|
$p = new Promise();
|
||||||
|
|
6
server/vendor/guzzlehttp/psr7/CHANGELOG.md
vendored
6
server/vendor/guzzlehttp/psr7/CHANGELOG.md
vendored
|
@ -1,5 +1,11 @@
|
||||||
# CHANGELOG
|
# CHANGELOG
|
||||||
|
|
||||||
|
## 1.2.3 - 2016-02-18
|
||||||
|
|
||||||
|
* Fixed support in `GuzzleHttp\Psr7\CachingStream` for seeking forward on remote
|
||||||
|
streams, which can sometimes return fewer bytes than requested with `fread`.
|
||||||
|
* Fixed handling of gzipped responses with FNAME headers.
|
||||||
|
|
||||||
## 1.2.2 - 2016-01-22
|
## 1.2.2 - 2016-01-22
|
||||||
|
|
||||||
* Added support for URIs without any authority.
|
* Added support for URIs without any authority.
|
||||||
|
|
4
server/vendor/guzzlehttp/psr7/README.md
vendored
4
server/vendor/guzzlehttp/psr7/README.md
vendored
|
@ -38,7 +38,7 @@ echo $composed(); // abc, 123. Above all listen to me.
|
||||||
|
|
||||||
`GuzzleHttp\Psr7\BufferStream`
|
`GuzzleHttp\Psr7\BufferStream`
|
||||||
|
|
||||||
Provides a buffer stream that can be written to to fill a buffer, and read
|
Provides a buffer stream that can be written to fill a buffer, and read
|
||||||
from to remove bytes from the buffer.
|
from to remove bytes from the buffer.
|
||||||
|
|
||||||
This stream returns a "hwm" metadata value that tells upstream consumers
|
This stream returns a "hwm" metadata value that tells upstream consumers
|
||||||
|
@ -106,7 +106,7 @@ echo $stream; // 0123456789
|
||||||
|
|
||||||
Compose stream implementations based on a hash of functions.
|
Compose stream implementations based on a hash of functions.
|
||||||
|
|
||||||
Allows for easy testing and extension of a provided stream without needing to
|
Allows for easy testing and extension of a provided stream without needing
|
||||||
to create a concrete class for a simple extension point.
|
to create a concrete class for a simple extension point.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
|
|
|
@ -60,9 +60,12 @@ class CachingStream implements StreamInterface
|
||||||
$diff = $byte - $this->stream->getSize();
|
$diff = $byte - $this->stream->getSize();
|
||||||
|
|
||||||
if ($diff > 0) {
|
if ($diff > 0) {
|
||||||
// If the seek byte is greater the number of read bytes, then read
|
// Read the remoteStream until we have read in at least the amount
|
||||||
// the difference of bytes to cache the bytes and inherently seek.
|
// of bytes requested, or we reach the end of the file.
|
||||||
$this->read($diff);
|
while ($diff > 0 && !$this->remoteStream->eof()) {
|
||||||
|
$this->read($diff);
|
||||||
|
$diff = $byte - $this->stream->getSize();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// We can just do a normal seek since we've already seen this byte.
|
// We can just do a normal seek since we've already seen this byte.
|
||||||
$this->stream->seek($byte);
|
$this->stream->seek($byte);
|
||||||
|
|
|
@ -20,10 +20,33 @@ class InflateStream implements StreamInterface
|
||||||
|
|
||||||
public function __construct(StreamInterface $stream)
|
public function __construct(StreamInterface $stream)
|
||||||
{
|
{
|
||||||
// Skip the first 10 bytes
|
// read the first 10 bytes, ie. gzip header
|
||||||
$stream = new LimitStream($stream, -1, 10);
|
$header = $stream->read(10);
|
||||||
|
$filenameHeaderLength = $this->getLengthOfPossibleFilenameHeader($stream, $header);
|
||||||
|
// Skip the header, that is 10 + length of filename + 1 (nil) bytes
|
||||||
|
$stream = new LimitStream($stream, -1, 10 + $filenameHeaderLength);
|
||||||
$resource = StreamWrapper::getResource($stream);
|
$resource = StreamWrapper::getResource($stream);
|
||||||
stream_filter_append($resource, 'zlib.inflate', STREAM_FILTER_READ);
|
stream_filter_append($resource, 'zlib.inflate', STREAM_FILTER_READ);
|
||||||
$this->stream = new Stream($resource);
|
$this->stream = new Stream($resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param StreamInterface $stream
|
||||||
|
* @param $header
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
private function getLengthOfPossibleFilenameHeader(StreamInterface $stream, $header)
|
||||||
|
{
|
||||||
|
$filename_header_length = 0;
|
||||||
|
|
||||||
|
if (substr(bin2hex($header), 6, 2) === '08') {
|
||||||
|
// we have a filename, read until nil
|
||||||
|
$filename_header_length = 1;
|
||||||
|
while ($stream->read(1) !== chr(0)) {
|
||||||
|
$filename_header_length++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $filename_header_length;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,6 +98,33 @@ class CachingStreamTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->assertEquals('ing', $this->body->read(3));
|
$this->assertEquals('ing', $this->body->read(3));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testCanSeekToReadBytesWithPartialBodyReturned()
|
||||||
|
{
|
||||||
|
$stream = fopen('php://temp', 'r+');
|
||||||
|
fwrite($stream, 'testing');
|
||||||
|
fseek($stream, 0);
|
||||||
|
|
||||||
|
$this->decorated = $this->getMockBuilder('\GuzzleHttp\Psr7\Stream')
|
||||||
|
->setConstructorArgs([$stream])
|
||||||
|
->setMethods(['read'])
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$this->decorated->expects($this->exactly(2))
|
||||||
|
->method('read')
|
||||||
|
->willReturnCallback(function($length) use ($stream){
|
||||||
|
return fread($stream, 2);
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->body = new CachingStream($this->decorated);
|
||||||
|
|
||||||
|
$this->assertEquals(0, $this->body->tell());
|
||||||
|
$this->body->seek(4, SEEK_SET);
|
||||||
|
$this->assertEquals(4, $this->body->tell());
|
||||||
|
|
||||||
|
$this->body->seek(0);
|
||||||
|
$this->assertEquals('test', $this->body->read(4));
|
||||||
|
}
|
||||||
|
|
||||||
public function testWritesToBufferStream()
|
public function testWritesToBufferStream()
|
||||||
{
|
{
|
||||||
$this->body->read(2);
|
$this->body->read(2);
|
||||||
|
|
|
@ -13,4 +13,27 @@ class InflateStreamtest extends \PHPUnit_Framework_TestCase
|
||||||
$b = new InflateStream($a);
|
$b = new InflateStream($a);
|
||||||
$this->assertEquals('test', (string) $b);
|
$this->assertEquals('test', (string) $b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testInflatesStreamsWithFilename()
|
||||||
|
{
|
||||||
|
$content = $this->getGzipStringWithFilename('test');
|
||||||
|
$a = Psr7\stream_for($content);
|
||||||
|
$b = new InflateStream($a);
|
||||||
|
$this->assertEquals('test', (string) $b);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getGzipStringWithFilename($original_string)
|
||||||
|
{
|
||||||
|
$gzipped = bin2hex(gzencode($original_string));
|
||||||
|
|
||||||
|
$header = substr($gzipped, 0, 20);
|
||||||
|
// set FNAME flag
|
||||||
|
$header[6]=0;
|
||||||
|
$header[7]=8;
|
||||||
|
// make a dummy filename
|
||||||
|
$filename = "64756d6d7900";
|
||||||
|
$rest = substr($gzipped, 20);
|
||||||
|
|
||||||
|
return hex2bin($header . $filename . $rest);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,7 +154,7 @@ class UriTest extends \PHPUnit_Framework_TestCase
|
||||||
[self::RFC3986_BASE, 'g;x=1/../y', 'http://a/b/c/y'],
|
[self::RFC3986_BASE, 'g;x=1/../y', 'http://a/b/c/y'],
|
||||||
['http://u@a/b/c/d;p?q', '.', 'http://u@a/b/c/'],
|
['http://u@a/b/c/d;p?q', '.', 'http://u@a/b/c/'],
|
||||||
['http://u:p@a/b/c/d;p?q', '.', 'http://u:p@a/b/c/'],
|
['http://u:p@a/b/c/d;p?q', '.', 'http://u:p@a/b/c/'],
|
||||||
//[self::RFC3986_BASE, 'http:g', 'http:g'],
|
['http://a/b/c/d/', 'e', 'http://a/b/c/d/e'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
server/vendor/php-opencloud/common/.gitignore
vendored
Normal file
10
server/vendor/php-opencloud/common/.gitignore
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
.idea/
|
||||||
|
.test/
|
||||||
|
coverage/
|
||||||
|
vendor/
|
||||||
|
|
||||||
|
*.pyc
|
||||||
|
|
||||||
|
phpunit.xml
|
||||||
|
coverage.xml
|
||||||
|
composer.lock
|
36
server/vendor/php-opencloud/common/composer.json
vendored
Normal file
36
server/vendor/php-opencloud/common/composer.json
vendored
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
"name": "php-opencloud/common",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Jamie Hannaford",
|
||||||
|
"email": "jamie.hannaford@rackspace.com",
|
||||||
|
"homepage" : "https://github.com/jamiehannaford"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"OpenCloud\\": "src/",
|
||||||
|
"OpenCloud\\Test\\": "tests/unit/",
|
||||||
|
"OpenCloud\\Integration\\": "tests/integration/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"repositories": [
|
||||||
|
{
|
||||||
|
"type": "vcs",
|
||||||
|
"url": "https://github.com/php-opencloud/Sami"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require": {
|
||||||
|
"php": "~7.0",
|
||||||
|
"guzzlehttp/guzzle": "~6.1",
|
||||||
|
"justinrainbow/json-schema": "~1.3"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "~4.0",
|
||||||
|
"sami/sami": "dev-master",
|
||||||
|
"psr/log": "~1.0",
|
||||||
|
"satooshi/php-coveralls": "~1.0",
|
||||||
|
"jakub-onderka/php-parallel-lint": "0.*",
|
||||||
|
"fabpot/php-cs-fixer": "~1.0"
|
||||||
|
}
|
||||||
|
}
|
21
server/vendor/php-opencloud/common/phpunit.xml.dist
vendored
Normal file
21
server/vendor/php-opencloud/common/phpunit.xml.dist
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<phpunit bootstrap="./vendor/autoload.php" colors="true">
|
||||||
|
|
||||||
|
<testsuites>
|
||||||
|
<testsuite name="OpenStack">
|
||||||
|
<directory>tests/unit</directory>
|
||||||
|
</testsuite>
|
||||||
|
</testsuites>
|
||||||
|
|
||||||
|
<filter>
|
||||||
|
<whitelist>
|
||||||
|
<directory suffix=".php">./src</directory>
|
||||||
|
<exclude>
|
||||||
|
<directory suffix="Interface.php">./src</directory>
|
||||||
|
<directory suffix="Api.php">./src</directory>
|
||||||
|
<directory suffix="Params.php">./src</directory>
|
||||||
|
</exclude>
|
||||||
|
</whitelist>
|
||||||
|
</filter>
|
||||||
|
|
||||||
|
</phpunit>
|
33
server/vendor/php-opencloud/common/src/Common/Api/AbstractApi.php
vendored
Normal file
33
server/vendor/php-opencloud/common/src/Common/Api/AbstractApi.php
vendored
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Api;
|
||||||
|
|
||||||
|
abstract class AbstractApi implements ApiInterface
|
||||||
|
{
|
||||||
|
protected $params;
|
||||||
|
|
||||||
|
protected function isRequired(array $param)
|
||||||
|
{
|
||||||
|
return array_merge($param, ['required' => true]);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function notRequired(array $param)
|
||||||
|
{
|
||||||
|
return array_merge($param, ['required' => false]);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function query(array $param)
|
||||||
|
{
|
||||||
|
return array_merge($param, ['location' => AbstractParams::QUERY]);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function url(array $param)
|
||||||
|
{
|
||||||
|
return array_merge($param, ['location' => AbstractParams::URL]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function documented(array $param)
|
||||||
|
{
|
||||||
|
return array_merge($param, ['required' => true]);
|
||||||
|
}
|
||||||
|
}
|
100
server/vendor/php-opencloud/common/src/Common/Api/AbstractParams.php
vendored
Normal file
100
server/vendor/php-opencloud/common/src/Common/Api/AbstractParams.php
vendored
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Api;
|
||||||
|
|
||||||
|
abstract class AbstractParams
|
||||||
|
{
|
||||||
|
// locations
|
||||||
|
const QUERY = 'query';
|
||||||
|
const HEADER = 'header';
|
||||||
|
const URL = 'url';
|
||||||
|
const JSON = 'json';
|
||||||
|
const RAW = 'raw';
|
||||||
|
|
||||||
|
// types
|
||||||
|
const STRING_TYPE = "string";
|
||||||
|
const BOOL_TYPE = "boolean";
|
||||||
|
const BOOLEAN_TYPE = self::BOOL_TYPE;
|
||||||
|
const OBJECT_TYPE = "object";
|
||||||
|
const ARRAY_TYPE = "array";
|
||||||
|
const NULL_TYPE = "NULL";
|
||||||
|
const INT_TYPE = 'integer';
|
||||||
|
const INTEGER_TYPE = self::INT_TYPE;
|
||||||
|
|
||||||
|
public static function isSupportedLocation($val)
|
||||||
|
{
|
||||||
|
return in_array($val, [self::QUERY, self::HEADER, self::URL, self::JSON, self::RAW]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function limit()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'type' => self::INT_TYPE,
|
||||||
|
'location' => 'query',
|
||||||
|
'description' => <<<DESC
|
||||||
|
This will limit the total amount of elements returned in a list up to the number specified. For example, specifying a
|
||||||
|
limit of 10 will return 10 elements, regardless of the actual count.
|
||||||
|
DESC
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function marker()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'type' => 'string',
|
||||||
|
'location' => 'query',
|
||||||
|
'description' => <<<DESC
|
||||||
|
Specifying a marker will begin the list from the value specified. Elements will have a particular attribute that
|
||||||
|
identifies them, such as a name or ID. The marker value will search for an element whose identifying attribute matches
|
||||||
|
the marker value, and begin the list from there.
|
||||||
|
DESC
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function id($type)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'description' => sprintf("The unique ID, or identifier, for the %s", $type),
|
||||||
|
'type' => self::STRING_TYPE,
|
||||||
|
'location' => self::JSON,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function idPath()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'type' => self::STRING_TYPE,
|
||||||
|
'location' => self::URL,
|
||||||
|
'description' => 'The unique ID of the resource',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function name($resource)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'description' => sprintf("The name of the %s", $resource),
|
||||||
|
'type' => self::STRING_TYPE,
|
||||||
|
'location' => self::JSON,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function sortDir()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'type' => self::STRING_TYPE,
|
||||||
|
'location' => self::QUERY,
|
||||||
|
'description' => "Sorts by one or more sets of attribute and sort direction combinations.",
|
||||||
|
'enum' => ['asc', 'desc']
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sortKey()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'type' => self::STRING_TYPE,
|
||||||
|
'location' => self::QUERY,
|
||||||
|
'description' => "Sorts by one or more sets of attribute and sort direction combinations.",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
20
server/vendor/php-opencloud/common/src/Common/Api/ApiInterface.php
vendored
Normal file
20
server/vendor/php-opencloud/common/src/Common/Api/ApiInterface.php
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Api;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All classes which implement this interface are a data representation of a remote OpenCloud API.
|
||||||
|
* They do not execute functionality, but instead return data for each API operation for other parts
|
||||||
|
* of the SDK to use. Usually, the data is injected into {@see OpenCloud\Common\Api\Operation} objects.
|
||||||
|
* The operation is then serialized into a {@see GuzzleHttp\Message\Request} and sent to the API.
|
||||||
|
*
|
||||||
|
* The reason for storing all the API-specific data is to decouple service information from client
|
||||||
|
* HTTP functionality. Too often it is mixed all across different layers, leading to duplication and
|
||||||
|
* no separation of concerns. The choice was made for storage in PHP classes, rather than YAML or JSON
|
||||||
|
* syntax, due to performance concerns.
|
||||||
|
*
|
||||||
|
* @package OpenCloud\Common\Api
|
||||||
|
*/
|
||||||
|
interface ApiInterface
|
||||||
|
{
|
||||||
|
}
|
136
server/vendor/php-opencloud/common/src/Common/Api/Operation.php
vendored
Normal file
136
server/vendor/php-opencloud/common/src/Common/Api/Operation.php
vendored
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Api;
|
||||||
|
|
||||||
|
use GuzzleHttp\Utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents an OpenCloud API operation. It encapsulates most aspects of the REST operation: its HTTP
|
||||||
|
* method, the URL path, its top-level JSON key, and all of its {@see Parameter} objects.
|
||||||
|
*
|
||||||
|
* An operation not only represents a remote operation, but it also provides the mechanism for executing it
|
||||||
|
* over HTTP. To do this, it uses a {@see ClientInterface} that allows a {@see GuzzleHttp\Message\Request}
|
||||||
|
* to be created from the user values provided. Once this request is assembled, it is then sent to the
|
||||||
|
* remote API and the response is returned to whoever first invoked the Operation class.
|
||||||
|
*
|
||||||
|
* @package OpenCloud\Common\Api
|
||||||
|
*/
|
||||||
|
class Operation
|
||||||
|
{
|
||||||
|
/** @var string The HTTP method */
|
||||||
|
private $method;
|
||||||
|
|
||||||
|
/** @var string The URL path */
|
||||||
|
private $path;
|
||||||
|
|
||||||
|
/** @var string The top-level JSON key */
|
||||||
|
private $jsonKey;
|
||||||
|
|
||||||
|
/** @var []Parameter The parameters of this operation */
|
||||||
|
private $params;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $definition The data definition (in array form) that will populate this
|
||||||
|
* operation. Usually this is retrieved from an {@see ApiInterface}
|
||||||
|
* object method.
|
||||||
|
*/
|
||||||
|
public function __construct(array $definition)
|
||||||
|
{
|
||||||
|
$this->method = $definition['method'];
|
||||||
|
$this->path = $definition['path'];
|
||||||
|
|
||||||
|
if (isset($definition['jsonKey'])) {
|
||||||
|
$this->jsonKey = $definition['jsonKey'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->params = self::toParamArray($definition['params']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getPath()
|
||||||
|
{
|
||||||
|
return $this->path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getMethod()
|
||||||
|
{
|
||||||
|
return $this->method;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether this operation supports a parameter.
|
||||||
|
*
|
||||||
|
* @param $key The name of a parameter
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function hasParam($key)
|
||||||
|
{
|
||||||
|
return isset($this->params[$key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $name
|
||||||
|
*
|
||||||
|
* @return Parameter
|
||||||
|
*/
|
||||||
|
public function getParam($name)
|
||||||
|
{
|
||||||
|
return isset($this->params[$name]) ? $this->params[$name] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getJsonKey()
|
||||||
|
{
|
||||||
|
return $this->jsonKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A convenience method that will take a generic array of data and convert it into an array of
|
||||||
|
* {@see Parameter} objects.
|
||||||
|
*
|
||||||
|
* @param array $data A generic data array
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function toParamArray(array $data)
|
||||||
|
{
|
||||||
|
$params = [];
|
||||||
|
|
||||||
|
foreach ($data as $name => $param) {
|
||||||
|
$params[$name] = new Parameter($param + ['name' => $name]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $params;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will validate all of the user-provided values and throw an exception if any
|
||||||
|
* failures are detected. This is useful for basic sanity-checking before a request is
|
||||||
|
* serialized and sent to the API.
|
||||||
|
*
|
||||||
|
* @param array $userValues The user-defined values
|
||||||
|
*
|
||||||
|
* @return bool TRUE if validation passes
|
||||||
|
* @throws \Exception If validate fails
|
||||||
|
*/
|
||||||
|
public function validate(array $userValues)
|
||||||
|
{
|
||||||
|
foreach ($this->params as $paramName => $param) {
|
||||||
|
if (array_key_exists($paramName, $userValues)) {
|
||||||
|
$param->validate($userValues[$paramName]);
|
||||||
|
} elseif ($param->isRequired()) {
|
||||||
|
throw new \Exception(sprintf('"%s" is a required option, but it was not provided', $paramName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
173
server/vendor/php-opencloud/common/src/Common/Api/Operator.php
vendored
Normal file
173
server/vendor/php-opencloud/common/src/Common/Api/Operator.php
vendored
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Api;
|
||||||
|
|
||||||
|
use function GuzzleHttp\uri_template;
|
||||||
|
use GuzzleHttp\ClientInterface;
|
||||||
|
use GuzzleHttp\Promise\Promise;
|
||||||
|
use OpenCloud\Common\Resource\ResourceInterface;
|
||||||
|
use OpenCloud\Common\Transport\RequestSerializer;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
abstract class Operator implements OperatorInterface
|
||||||
|
{
|
||||||
|
/** @var ClientInterface */
|
||||||
|
protected $client;
|
||||||
|
|
||||||
|
/** @var ApiInterface */
|
||||||
|
protected $api;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function __construct(ClientInterface $client, ApiInterface $api)
|
||||||
|
{
|
||||||
|
$this->client = $client;
|
||||||
|
$this->api = $api;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Magic method for dictating how objects are rendered when var_dump is called.
|
||||||
|
* For the benefit of users, extremely verbose and heavy properties (such as HTTP clients) are
|
||||||
|
* removed to provide easier access to normal state, such as resource attributes.
|
||||||
|
*
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function __debugInfo()
|
||||||
|
{
|
||||||
|
$excludedVars = ['client', 'errorBuilder', 'api'];
|
||||||
|
|
||||||
|
$output = [];
|
||||||
|
|
||||||
|
foreach (get_object_vars($this) as $key => $val) {
|
||||||
|
if (!in_array($key, $excludedVars)) {
|
||||||
|
$output[$key] = $val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a populated Operation according to the definition and values provided. A
|
||||||
|
* HTTP client is also injected into the object to allow it to communicate with the remote API.
|
||||||
|
*
|
||||||
|
* @param array $definition The data that dictates how the operation works
|
||||||
|
*
|
||||||
|
* @return Operation
|
||||||
|
*/
|
||||||
|
public function getOperation(array $definition)
|
||||||
|
{
|
||||||
|
return new Operation($definition);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function sendRequest(Operation $operation, array $userValues = [], $async = false)
|
||||||
|
{
|
||||||
|
$operation->validate($userValues);
|
||||||
|
|
||||||
|
$options = (new RequestSerializer)->serializeOptions($operation, $userValues);
|
||||||
|
$method = $async ? 'requestAsync' : 'request';
|
||||||
|
$uri = uri_template($operation->getPath(), $userValues);
|
||||||
|
|
||||||
|
return $this->client->$method($operation->getMethod(), $uri, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function execute(array $definition, array $userValues = [])
|
||||||
|
{
|
||||||
|
return $this->sendRequest($this->getOperation($definition), $userValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function executeAsync(array $definition, array $userValues = [])
|
||||||
|
{
|
||||||
|
return $this->sendRequest($this->getOperation($definition), $userValues, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function model($class, $data = null)
|
||||||
|
{
|
||||||
|
$model = new $class($this->client, $this->api);
|
||||||
|
|
||||||
|
// @codeCoverageIgnoreStart
|
||||||
|
if (!$model instanceof ResourceInterface) {
|
||||||
|
throw new \RuntimeException(sprintf('%s does not implement %s', $class, ResourceInterface::class));
|
||||||
|
}
|
||||||
|
// @codeCoverageIgnoreEnd
|
||||||
|
|
||||||
|
if ($data instanceof ResponseInterface) {
|
||||||
|
$model->populateFromResponse($data);
|
||||||
|
} elseif (is_array($data)) {
|
||||||
|
$model->populateFromArray($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will create a new instance of this class with the current HTTP client and API injected in. This
|
||||||
|
* is useful when enumerating over a collection since multiple copies of the same resource class
|
||||||
|
* are needed.
|
||||||
|
*
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
public function newInstance()
|
||||||
|
{
|
||||||
|
return new static($this->client, $this->api);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \GuzzleHttp\Psr7\Uri
|
||||||
|
*/
|
||||||
|
protected function getHttpBaseUrl()
|
||||||
|
{
|
||||||
|
return $this->client->getConfig('base_uri');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Magic method which intercepts async calls, finds the sequential version, and wraps it in a
|
||||||
|
* {@see Promise} object. In order for this to happen, the called methods need to be in the
|
||||||
|
* following format: `createAsync`, where `create` is the sequential method being wrapped.
|
||||||
|
*
|
||||||
|
* @param $methodName The name of the method being invoked.
|
||||||
|
* @param $args The arguments to be passed to the sequential method.
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException If method does not exist
|
||||||
|
*
|
||||||
|
* @return Promise
|
||||||
|
*/
|
||||||
|
public function __call($methodName, $args)
|
||||||
|
{
|
||||||
|
$e = function ($name) {
|
||||||
|
return new \RuntimeException(sprintf('%s::%s is not defined', get_class($this), $name));
|
||||||
|
};
|
||||||
|
|
||||||
|
if (substr($methodName, -5) === 'Async') {
|
||||||
|
$realMethod = substr($methodName, 0, -5);
|
||||||
|
if (!method_exists($this, $realMethod)) {
|
||||||
|
throw $e($realMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
$promise = new Promise(
|
||||||
|
function () use (&$promise, $realMethod, $args) {
|
||||||
|
$value = call_user_func_array([$this, $realMethod], $args);
|
||||||
|
$promise->resolve($value);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return $promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw $e($methodName);
|
||||||
|
}
|
||||||
|
}
|
51
server/vendor/php-opencloud/common/src/Common/Api/OperatorInterface.php
vendored
Normal file
51
server/vendor/php-opencloud/common/src/Common/Api/OperatorInterface.php
vendored
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Api;
|
||||||
|
|
||||||
|
use GuzzleHttp\ClientInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An operator is any resource or service that can invoke and send REST operations. In other words, it
|
||||||
|
* is any class that can send requests and receive responses with a HTTP client. To do this
|
||||||
|
* it needs two things: a {@see ClientInterface} for handling HTTP transactions and an {@see ApiInterface}
|
||||||
|
* for handling how operations are created.
|
||||||
|
*
|
||||||
|
* @package OpenCloud\Common\Api
|
||||||
|
*/
|
||||||
|
interface OperatorInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param ClientInterface $client The HTTP client responsible for handling HTTP transactions
|
||||||
|
* @param ApiInterface $api The data API class that dictates how REST operations are structured
|
||||||
|
*/
|
||||||
|
public function __construct(ClientInterface $client, ApiInterface $api);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A convenience method that assembles an operation and sends it to the remote API
|
||||||
|
*
|
||||||
|
* @param array $definition The data that dictates how the operation works
|
||||||
|
* @param array $userValues The user-defined values that populate the request
|
||||||
|
*
|
||||||
|
* @return \Psr\Http\Message\ResponseInterface
|
||||||
|
*/
|
||||||
|
public function execute(array $definition, array $userValues = []);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A convenience method that assembles an operation and asynchronously sends it to the remote API
|
||||||
|
*
|
||||||
|
* @param array $definition The data that dictates how the operation works
|
||||||
|
* @param array $userValues The user-defined values that populate the request
|
||||||
|
*
|
||||||
|
* @return \GuzzleHttp\Promise\PromiseInterface
|
||||||
|
*/
|
||||||
|
public function executeAsync(array $definition, array $userValues = []);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $name The name of the model class.
|
||||||
|
* @param mixed $data Either a {@see ResponseInterface} or data array that will populate the newly
|
||||||
|
* created model class.
|
||||||
|
*
|
||||||
|
* @return \OpenCloud\Common\Resource\ResourceInterface
|
||||||
|
*/
|
||||||
|
public function model($name, $data = null);
|
||||||
|
}
|
389
server/vendor/php-opencloud/common/src/Common/Api/Parameter.php
vendored
Normal file
389
server/vendor/php-opencloud/common/src/Common/Api/Parameter.php
vendored
Normal file
|
@ -0,0 +1,389 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Api;
|
||||||
|
|
||||||
|
use OpenCloud\Common\HydratorStrategyTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an individual request parameter in a RESTful operation. A parameter can take on many forms:
|
||||||
|
* in a URL path, in a URL query, in a JSON body, and in a HTTP header. It is worth documenting brifly each
|
||||||
|
* variety of parameter:
|
||||||
|
*
|
||||||
|
* * Header parameters are those which populate a HTTP header in a request. Header parameters can have
|
||||||
|
* aliases; for example, a user-facing name of "Foo" can be sent over the wire as "X-Foo_Bar", as defined
|
||||||
|
* by ``sentAs``. Prefixes can also be used.
|
||||||
|
*
|
||||||
|
* * Query parameters are those which populate a URL query parameter. The value is therefore usually
|
||||||
|
* confined to a string.
|
||||||
|
*
|
||||||
|
* * JSON parameters are those which populate a JSON request body. These are the most complex variety
|
||||||
|
* of Parameter, since there are so many different ways a JSON document can be constructed. The SDK
|
||||||
|
* supports deep-nesting according to a XPath syntax; for more information, see {@see \OpenCloud\Common\JsonPath}.
|
||||||
|
* Nested object and array properties are also supported since JSON is a recursive data type. What
|
||||||
|
* this means is that a Parameter can have an assortment of child Parameters, one for each object
|
||||||
|
* property or array element.
|
||||||
|
*
|
||||||
|
* * Raw parameters are those which populate a non-JSON request body. This is typically used for
|
||||||
|
* uploading payloads (such as Swift object data) to a remote API.
|
||||||
|
*
|
||||||
|
* * Path parameters are those which populate a URL path. They are serialized according to URL
|
||||||
|
* placeholders.
|
||||||
|
*
|
||||||
|
* @package OpenCloud\Common\Api
|
||||||
|
*/
|
||||||
|
class Parameter
|
||||||
|
{
|
||||||
|
use HydratorStrategyTrait;
|
||||||
|
|
||||||
|
const DEFAULT_LOCATION = 'json';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The human-friendly name of the parameter. This is what the user will input.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The alias for this parameter. Although the user will always interact with the human-friendly $name property,
|
||||||
|
* the $sentAs is what's used over the wire.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $sentAs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For array parameters (for example, an array of security group names when creating a server), each array element
|
||||||
|
* will need to adhere to a common schema. For the aforementioned example, each element will need to be a string.
|
||||||
|
* For more complicated parameters, you might be validated an array of complicated objects.
|
||||||
|
*
|
||||||
|
* @var Parameter
|
||||||
|
*/
|
||||||
|
private $itemSchema;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For object parameters, each property will need to adhere to a specific schema. For every property in the
|
||||||
|
* object, it has its own schema - meaning that this property is a hash of name/schema pairs.
|
||||||
|
*
|
||||||
|
* The *only* exception to this rule is for metadata parameters, which are arbitrary key/value pairs. Since it does
|
||||||
|
* not make sense to have a schema for each metadata key, a common schema is use for every one. So instead of this
|
||||||
|
* property being a hash of schemas, it is a single Parameter object instead. This single Parameter schema will
|
||||||
|
* then be applied to each metadata key provided.
|
||||||
|
*
|
||||||
|
* @var []Parameter|Parameter
|
||||||
|
*/
|
||||||
|
private $properties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The value's PHP type which this parameter represents; either "string", "bool", "object", "array", "NULL".
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether this parameter requires a value from the user.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private $required;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The location in the HTTP request where this parameter will populate; either "header", "url", "query", "raw" or
|
||||||
|
* "json".
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $location;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Relevant to "json" location parameters only. This property allows for deep nesting through the use of
|
||||||
|
* {@see OpenCloud\Common\JsonPath}.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $path;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows for the prefixing of parameter names.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $prefix;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The enum values for which this param is restricted.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $enum;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
*/
|
||||||
|
public function __construct(array $data)
|
||||||
|
{
|
||||||
|
$this->hydrate($data);
|
||||||
|
|
||||||
|
$this->required = (bool)$this->required;
|
||||||
|
|
||||||
|
$this->stockLocation($data);
|
||||||
|
$this->stockItemSchema($data);
|
||||||
|
$this->stockProperties($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function stockLocation(array $data)
|
||||||
|
{
|
||||||
|
$this->location = isset($data['location']) ? $data['location'] : self::DEFAULT_LOCATION;
|
||||||
|
|
||||||
|
if (!AbstractParams::isSupportedLocation($this->location)) {
|
||||||
|
throw new \RuntimeException(sprintf("%s is not a permitted location", $this->location));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function stockItemSchema(array $data)
|
||||||
|
{
|
||||||
|
if (isset($data['items'])) {
|
||||||
|
$this->itemSchema = new Parameter($data['items']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function stockProperties(array $data)
|
||||||
|
{
|
||||||
|
if (isset($data['properties'])) {
|
||||||
|
if (stripos($this->name, 'metadata') !== false) {
|
||||||
|
$this->properties = new Parameter($data['properties']);
|
||||||
|
} else {
|
||||||
|
foreach ($data['properties'] as $name => $property) {
|
||||||
|
$this->properties[$name] = new Parameter($property + ['name' => $name]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the name that will be used over the wire.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return $this->sentAs ?: $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether the user must provide a value for this parameter.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isRequired()
|
||||||
|
{
|
||||||
|
return $this->required === true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates a given user value and checks whether it passes basic sanity checking, such as types.
|
||||||
|
*
|
||||||
|
* @param $userValues The value provided by the user
|
||||||
|
*
|
||||||
|
* @return bool TRUE if the validation passes
|
||||||
|
* @throws \Exception If validation fails
|
||||||
|
*/
|
||||||
|
public function validate($userValues)
|
||||||
|
{
|
||||||
|
$this->validateEnums($userValues);
|
||||||
|
$this->validateType($userValues);
|
||||||
|
|
||||||
|
if ($this->isArray()) {
|
||||||
|
$this->validateArray($userValues);
|
||||||
|
} elseif ($this->isObject()) {
|
||||||
|
$this->validateObject($userValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function validateEnums($userValues)
|
||||||
|
{
|
||||||
|
if (!empty($this->enum) && $this->type == 'string' && !in_array($userValues, $this->enum)) {
|
||||||
|
throw new \Exception(sprintf(
|
||||||
|
'The only permitted values are %s. You provided %s', implode(', ', $this->enum), print_r($userValues, true)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function validateType($userValues)
|
||||||
|
{
|
||||||
|
if (!$this->hasCorrectType($userValues)) {
|
||||||
|
throw new \Exception(sprintf(
|
||||||
|
'The key provided "%s" has the wrong value type. You provided %s (%s) but was expecting %s',
|
||||||
|
$this->name, print_r($userValues, true), gettype($userValues), $this->type
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function validateArray($userValues)
|
||||||
|
{
|
||||||
|
foreach ($userValues as $userValue) {
|
||||||
|
$this->itemSchema->validate($userValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function validateObject($userValues)
|
||||||
|
{
|
||||||
|
foreach ($userValues as $key => $userValue) {
|
||||||
|
$property = $this->getNestedProperty($key);
|
||||||
|
$property->validate($userValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal method which retrieves a nested property for object parameters.
|
||||||
|
*
|
||||||
|
* @param $key The name of the child parameter
|
||||||
|
*
|
||||||
|
* @returns Parameter
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
private function getNestedProperty($key)
|
||||||
|
{
|
||||||
|
if (stripos($this->name, 'metadata') !== false && $this->properties instanceof Parameter) {
|
||||||
|
return $this->properties;
|
||||||
|
} elseif (isset($this->properties[$key])) {
|
||||||
|
return $this->properties[$key];
|
||||||
|
} else {
|
||||||
|
throw new \Exception(sprintf('The key provided "%s" is not defined', $key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal method which indicates whether the user value is of the same type as the one expected
|
||||||
|
* by this parameter.
|
||||||
|
*
|
||||||
|
* @param $userValue The value being checked
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function hasCorrectType($userValue)
|
||||||
|
{
|
||||||
|
// Helper fn to see whether an array is associative (i.e. a JSON object)
|
||||||
|
$isAssociative = function ($value) {
|
||||||
|
return is_array($value) && array_keys($value) !== range(0, count($value) - 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
// For params defined as objects, we'll let the user get away with
|
||||||
|
// passing in an associative array - since it's effectively a hash
|
||||||
|
if ($this->type == 'object' && $isAssociative($userValue)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (class_exists($this->type) || interface_exists($this->type)) {
|
||||||
|
return is_a($userValue, $this->type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->type) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return gettype($userValue) == $this->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether this parameter represents an array type
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isArray()
|
||||||
|
{
|
||||||
|
return $this->type == 'array' && $this->itemSchema instanceof Parameter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether this parameter represents an object type
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isObject()
|
||||||
|
{
|
||||||
|
return $this->type == 'object' && !empty($this->properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLocation()
|
||||||
|
{
|
||||||
|
return $this->location;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies whether the given location matches the parameter's location.
|
||||||
|
*
|
||||||
|
* @param $value
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function hasLocation($value)
|
||||||
|
{
|
||||||
|
return $this->location == $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the parameter's path.
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function getPath()
|
||||||
|
{
|
||||||
|
return $this->path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the common schema that an array parameter applies to all its child elements.
|
||||||
|
*
|
||||||
|
* @return Parameter
|
||||||
|
*/
|
||||||
|
public function getItemSchema()
|
||||||
|
{
|
||||||
|
return $this->itemSchema;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the name of the parameter to a new value
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
*/
|
||||||
|
public function setName($name)
|
||||||
|
{
|
||||||
|
$this->name = $name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the child parameter for an object parameter.
|
||||||
|
*
|
||||||
|
* @param string $name The name of the child property
|
||||||
|
*
|
||||||
|
* @return null|Parameter
|
||||||
|
*/
|
||||||
|
public function getProperty($name)
|
||||||
|
{
|
||||||
|
if ($this->properties instanceof Parameter) {
|
||||||
|
$this->properties->setName($name);
|
||||||
|
return $this->properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isset($this->properties[$name]) ? $this->properties[$name] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the prefix for a parameter, if any.
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function getPrefix()
|
||||||
|
{
|
||||||
|
return $this->prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPrefixedName()
|
||||||
|
{
|
||||||
|
return $this->prefix . $this->getName();
|
||||||
|
}
|
||||||
|
}
|
67
server/vendor/php-opencloud/common/src/Common/ArrayAccessTrait.php
vendored
Normal file
67
server/vendor/php-opencloud/common/src/Common/ArrayAccessTrait.php
vendored
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encapsulates common logic for classes which implement the SPL \ArrayAccess interface.
|
||||||
|
*
|
||||||
|
* @package OpenCloud\Common
|
||||||
|
*/
|
||||||
|
trait ArrayAccessTrait
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The internal state that this object represents
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $internalState = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets an internal key with a value.
|
||||||
|
*
|
||||||
|
* @param string $offset
|
||||||
|
* @param mixed $value
|
||||||
|
*/
|
||||||
|
public function offsetSet($offset, $value)
|
||||||
|
{
|
||||||
|
if (null === $offset) {
|
||||||
|
$this->internalState[] = $value;
|
||||||
|
} else {
|
||||||
|
$this->internalState[$offset] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether an internal key exists.
|
||||||
|
*
|
||||||
|
* @param string $offset
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function offsetExists($offset)
|
||||||
|
{
|
||||||
|
return isset($this->internalState[$offset]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsets an internal key.
|
||||||
|
*
|
||||||
|
* @param string $offset
|
||||||
|
*/
|
||||||
|
public function offsetUnset($offset)
|
||||||
|
{
|
||||||
|
unset($this->internalState[$offset]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves an internal key.
|
||||||
|
*
|
||||||
|
* @param string $offset
|
||||||
|
*
|
||||||
|
* @return mixed|null
|
||||||
|
*/
|
||||||
|
public function offsetGet($offset)
|
||||||
|
{
|
||||||
|
return $this->offsetExists($offset) ? $this->internalState[$offset] : null;
|
||||||
|
}
|
||||||
|
}
|
73
server/vendor/php-opencloud/common/src/Common/Auth/AuthHandler.php
vendored
Normal file
73
server/vendor/php-opencloud/common/src/Common/Auth/AuthHandler.php
vendored
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Auth;
|
||||||
|
|
||||||
|
use function GuzzleHttp\Psr7\modify_request;
|
||||||
|
use Psr\Http\Message\RequestInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is responsible for three tasks:
|
||||||
|
*
|
||||||
|
* 1. performing the initial authentication for OpenCloud services
|
||||||
|
* 2. populating the ``X-Auth-Token`` header for every HTTP request
|
||||||
|
* 3. checking the token expiry before each request, and re-authenticating if necessary
|
||||||
|
*/
|
||||||
|
class AuthHandler
|
||||||
|
{
|
||||||
|
private $nextHandler;
|
||||||
|
|
||||||
|
private $tokenGenerator;
|
||||||
|
|
||||||
|
private $token;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param callable $nextHandler
|
||||||
|
* @param callable $tokenGenerator
|
||||||
|
*/
|
||||||
|
public function __construct(callable $nextHandler, callable $tokenGenerator, Token $token = null)
|
||||||
|
{
|
||||||
|
$this->nextHandler = $nextHandler;
|
||||||
|
$this->tokenGenerator = $tokenGenerator;
|
||||||
|
$this->token = $token;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is invoked before every HTTP request is sent to the API. When this happens, it
|
||||||
|
* checks to see whether a token is set and valid, and then sets the ``X-Auth-Token`` header
|
||||||
|
* for the HTTP request before letting it continue on its merry way.
|
||||||
|
*
|
||||||
|
* @param RequestInterface $request
|
||||||
|
* @param array $options
|
||||||
|
*
|
||||||
|
* @return mixed|void
|
||||||
|
*/
|
||||||
|
public function __invoke(RequestInterface $request, array $options)
|
||||||
|
{
|
||||||
|
$fn = $this->nextHandler;
|
||||||
|
|
||||||
|
if ($this->shouldIgnore($request)) {
|
||||||
|
return $fn($request, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->token || $this->token->hasExpired()) {
|
||||||
|
$this->token = call_user_func($this->tokenGenerator);
|
||||||
|
}
|
||||||
|
|
||||||
|
$modify = ['set_headers' => ['X-Auth-Token' => $this->token->getId()]];
|
||||||
|
|
||||||
|
return $fn(modify_request($request, $modify), $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal method which prevents infinite recursion. For certain requests, like the initial
|
||||||
|
* auth call itself, we do NOT want to send a token.
|
||||||
|
*
|
||||||
|
* @param RequestInterface $request
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function shouldIgnore(RequestInterface $request)
|
||||||
|
{
|
||||||
|
return strpos((string) $request->getUri(), 'tokens') !== false && $request->getMethod() == 'POST';
|
||||||
|
}
|
||||||
|
}
|
20
server/vendor/php-opencloud/common/src/Common/Auth/Catalog.php
vendored
Normal file
20
server/vendor/php-opencloud/common/src/Common/Auth/Catalog.php
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Auth;
|
||||||
|
|
||||||
|
interface Catalog
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Attempts to retrieve the base URL for a service from the catalog according to the arguments provided.
|
||||||
|
*
|
||||||
|
* @param string $name The name of the service as it appears in the catalog
|
||||||
|
* @param string $type The type of the service as it appears in the catalog
|
||||||
|
* @param string $region The region of the service as it appears in the catalog
|
||||||
|
* @param string $urlType The URL type of the service as it appears in the catalog
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException If no endpoint is matched
|
||||||
|
*
|
||||||
|
* @returns string
|
||||||
|
*/
|
||||||
|
public function getServiceUrl($name, $type, $region, $urlType);
|
||||||
|
}
|
13
server/vendor/php-opencloud/common/src/Common/Auth/IdentityService.php
vendored
Normal file
13
server/vendor/php-opencloud/common/src/Common/Auth/IdentityService.php
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Auth;
|
||||||
|
|
||||||
|
interface IdentityService
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Authenticates and retrieves back a token and catalog.
|
||||||
|
*
|
||||||
|
* @return array The FIRST key is {@see Token} instance, the SECOND key is a {@see Catalog} instance
|
||||||
|
*/
|
||||||
|
public function authenticate(array $options);
|
||||||
|
}
|
15
server/vendor/php-opencloud/common/src/Common/Auth/Token.php
vendored
Normal file
15
server/vendor/php-opencloud/common/src/Common/Auth/Token.php
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Auth;
|
||||||
|
|
||||||
|
interface Token
|
||||||
|
{
|
||||||
|
public function getId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether the token has expired or not.
|
||||||
|
*
|
||||||
|
* @return bool TRUE if the token has expired, FALSE if it is still valid
|
||||||
|
*/
|
||||||
|
public function hasExpired();
|
||||||
|
}
|
40
server/vendor/php-opencloud/common/src/Common/Error/BadResponseError.php
vendored
Normal file
40
server/vendor/php-opencloud/common/src/Common/Error/BadResponseError.php
vendored
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Error;
|
||||||
|
|
||||||
|
use Psr\Http\Message\RequestInterface;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a HTTP-specific error, caused by 4xx or 5xx response statuses.
|
||||||
|
*
|
||||||
|
* @package OpenCloud\Common\Error
|
||||||
|
*/
|
||||||
|
class BadResponseError extends BaseError
|
||||||
|
{
|
||||||
|
/** @var RequestInterface */
|
||||||
|
private $request;
|
||||||
|
|
||||||
|
/** @var ResponseInterface */
|
||||||
|
private $response;
|
||||||
|
|
||||||
|
public function setRequest(RequestInterface $request)
|
||||||
|
{
|
||||||
|
$this->request = $request;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setResponse(ResponseInterface $response)
|
||||||
|
{
|
||||||
|
$this->response = $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRequest()
|
||||||
|
{
|
||||||
|
return $this->request;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getResponse()
|
||||||
|
{
|
||||||
|
return $this->response;
|
||||||
|
}
|
||||||
|
}
|
12
server/vendor/php-opencloud/common/src/Common/Error/BaseError.php
vendored
Normal file
12
server/vendor/php-opencloud/common/src/Common/Error/BaseError.php
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base error class.
|
||||||
|
*
|
||||||
|
* @package OpenCloud\Common\Error
|
||||||
|
*/
|
||||||
|
class BaseError extends \Exception
|
||||||
|
{
|
||||||
|
}
|
179
server/vendor/php-opencloud/common/src/Common/Error/Builder.php
vendored
Normal file
179
server/vendor/php-opencloud/common/src/Common/Error/Builder.php
vendored
Normal file
|
@ -0,0 +1,179 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Error;
|
||||||
|
|
||||||
|
use GuzzleHttp\Client;
|
||||||
|
use GuzzleHttp\ClientInterface;
|
||||||
|
use GuzzleHttp\Exception\ClientException;
|
||||||
|
use Psr\Http\Message\MessageInterface;
|
||||||
|
use Psr\Http\Message\RequestInterface;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class responsible for building meaningful exceptions. For HTTP problems, it produces a {@see HttpError}
|
||||||
|
* exception, and supplies a error message with reasonable defaults. For user input problems, it produces a
|
||||||
|
* {@see UserInputError} exception. For both, the problem is described, a potential solution is offered and
|
||||||
|
* a link to further information is included.
|
||||||
|
*
|
||||||
|
* @package OpenCloud\Common\Error
|
||||||
|
*/
|
||||||
|
class Builder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The default domain to use for further link documentation.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $docDomain = 'http://docs.php-opencloud.com/en/latest/';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The HTTP client required to validate the further links.
|
||||||
|
*
|
||||||
|
* @var ClientInterface
|
||||||
|
*/
|
||||||
|
private $client;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ClientInterface $client
|
||||||
|
*/
|
||||||
|
public function __construct(ClientInterface $client = null)
|
||||||
|
{
|
||||||
|
$this->client = $client ?: new Client();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal method used when outputting headers in the error description.
|
||||||
|
*
|
||||||
|
* @param $name
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function header($name)
|
||||||
|
{
|
||||||
|
return sprintf("%s\n%s\n", $name, str_repeat('~', strlen($name)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Before outputting custom links, it is validated to ensure that the user is not
|
||||||
|
* directed off to a broken link. If a 404 is detected, it is hidden.
|
||||||
|
*
|
||||||
|
* @param $link The proposed link
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function linkIsValid($link)
|
||||||
|
{
|
||||||
|
$link = $this->docDomain . $link;
|
||||||
|
|
||||||
|
try {
|
||||||
|
return $this->client->request('HEAD', $link)->getStatusCode() < 400;
|
||||||
|
} catch (ClientException $e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param MessageInterface $message
|
||||||
|
*
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function str(MessageInterface $message)
|
||||||
|
{
|
||||||
|
if ($message instanceof RequestInterface) {
|
||||||
|
$msg = trim($message->getMethod() . ' '
|
||||||
|
. $message->getRequestTarget())
|
||||||
|
. ' HTTP/' . $message->getProtocolVersion();
|
||||||
|
if (!$message->hasHeader('host')) {
|
||||||
|
$msg .= "\r\nHost: " . $message->getUri()->getHost();
|
||||||
|
}
|
||||||
|
} elseif ($message instanceof ResponseInterface) {
|
||||||
|
$msg = 'HTTP/' . $message->getProtocolVersion() . ' '
|
||||||
|
. $message->getStatusCode() . ' '
|
||||||
|
. $message->getReasonPhrase();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($message->getHeaders() as $name => $values) {
|
||||||
|
$msg .= "\r\n{$name}: " . implode(', ', $values);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($message->getBody()->getSize() < ini_get('memory_limit')) {
|
||||||
|
$msg .= "\r\n\r\n" . $message->getBody();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method responsible for constructing and returning {@see BadResponseError} exceptions.
|
||||||
|
*
|
||||||
|
* @param RequestInterface $request The faulty request
|
||||||
|
* @param ResponseInterface $response The error-filled response
|
||||||
|
*
|
||||||
|
* @return BadResponseError
|
||||||
|
*/
|
||||||
|
public function httpError(RequestInterface $request, ResponseInterface $response)
|
||||||
|
{
|
||||||
|
$message = $this->header('HTTP Error');
|
||||||
|
|
||||||
|
$message .= sprintf("The remote server returned a \"%d %s\" error for the following transaction:\n\n",
|
||||||
|
$response->getStatusCode(), $response->getReasonPhrase());
|
||||||
|
|
||||||
|
$message .= $this->header('Request');
|
||||||
|
$message .= trim($this->str($request)) . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
|
$message .= $this->header('Response');
|
||||||
|
$message .= trim($this->str($response)) . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
|
$message .= $this->header('Further information');
|
||||||
|
$message .= $this->getStatusCodeMessage($response->getStatusCode());
|
||||||
|
|
||||||
|
$message .= "Visit http://docs.php-opencloud.com/en/latest/http-codes for more information about debugging "
|
||||||
|
. "HTTP status codes, or file a support issue on https://github.com/php-opencloud/openstack/issues.";
|
||||||
|
|
||||||
|
$e = new BadResponseError($message);
|
||||||
|
$e->setRequest($request);
|
||||||
|
$e->setResponse($response);
|
||||||
|
|
||||||
|
return $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getStatusCodeMessage($statusCode)
|
||||||
|
{
|
||||||
|
$errors = [
|
||||||
|
400 => 'Please ensure that your input values are valid and well-formed. ',
|
||||||
|
401 => 'Please ensure that your authentication credentials are valid. ',
|
||||||
|
404 => "Please ensure that the resource you're trying to access actually exists. ",
|
||||||
|
500 => 'Please try this operation again once you know the remote server is operational. ',
|
||||||
|
];
|
||||||
|
|
||||||
|
return isset($errors[$statusCode]) ? $errors[$statusCode] : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method responsible for constructing and returning {@see UserInputError} exceptions.
|
||||||
|
*
|
||||||
|
* @param string $expectedType The type that was expected from the user
|
||||||
|
* @param mixed $userValue The incorrect value the user actually provided
|
||||||
|
* @param string|null $furtherLink A link to further information if necessary (optional).
|
||||||
|
*
|
||||||
|
* @return UserInputError
|
||||||
|
*/
|
||||||
|
public function userInputError($expectedType, $userValue, $furtherLink = null)
|
||||||
|
{
|
||||||
|
$message = $this->header('User Input Error');
|
||||||
|
|
||||||
|
$message .= sprintf("%s was expected, but the following value was passed in:\n\n%s\n",
|
||||||
|
$expectedType, print_r($userValue, true));
|
||||||
|
|
||||||
|
$message .= "Please ensure that the value adheres to the expectation above. ";
|
||||||
|
|
||||||
|
if ($furtherLink && $this->linkIsValid($furtherLink)) {
|
||||||
|
$message .= sprintf("Visit %s for more information about input arguments. ", $this->docDomain . $furtherLink);
|
||||||
|
}
|
||||||
|
|
||||||
|
$message .= 'If you run into trouble, please open a support issue on https://github.com/php-opencloud/openstack/issues.';
|
||||||
|
|
||||||
|
return new UserInputError($message);
|
||||||
|
}
|
||||||
|
}
|
12
server/vendor/php-opencloud/common/src/Common/Error/NotImplementedError.php
vendored
Normal file
12
server/vendor/php-opencloud/common/src/Common/Error/NotImplementedError.php
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error to indicate functionality which has not been implemented yet.
|
||||||
|
*
|
||||||
|
* @package OpenCloud\Common\Error
|
||||||
|
*/
|
||||||
|
class NotImplementedError extends BaseError
|
||||||
|
{
|
||||||
|
}
|
12
server/vendor/php-opencloud/common/src/Common/Error/UserInputError.php
vendored
Normal file
12
server/vendor/php-opencloud/common/src/Common/Error/UserInputError.php
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a user input error, caused by an incorrect type or malformed value.
|
||||||
|
*
|
||||||
|
* @package OpenCloud\Common\Error
|
||||||
|
*/
|
||||||
|
class UserInputError extends BaseError
|
||||||
|
{
|
||||||
|
}
|
35
server/vendor/php-opencloud/common/src/Common/HydratorStrategyTrait.php
vendored
Normal file
35
server/vendor/php-opencloud/common/src/Common/HydratorStrategyTrait.php
vendored
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents common functionality for populating, or "hydrating", an object with arbitrary data.
|
||||||
|
*
|
||||||
|
* @package OpenCloud\Common
|
||||||
|
*/
|
||||||
|
trait HydratorStrategyTrait
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Hydrates an object with set data
|
||||||
|
*
|
||||||
|
* @param array $data The data to set
|
||||||
|
* @param array $aliases Any aliases
|
||||||
|
*/
|
||||||
|
private function hydrate(array $data, array $aliases = [])
|
||||||
|
{
|
||||||
|
foreach ($data as $key => $val) {
|
||||||
|
$key = isset($aliases[$key]) ? $aliases[$key] : $key;
|
||||||
|
if (property_exists($this, $key)) {
|
||||||
|
$this->$key = $val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function set($key, $property, array $data, callable $fn = null)
|
||||||
|
{
|
||||||
|
if (isset($data[$key]) && property_exists($this, $property)) {
|
||||||
|
$value = $fn ? call_user_func($fn, $data[$key]) : $data[$key];
|
||||||
|
$this->$property = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
119
server/vendor/php-opencloud/common/src/Common/JsonPath.php
vendored
Normal file
119
server/vendor/php-opencloud/common/src/Common/JsonPath.php
vendored
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class allows arbitrary data structures to be inserted into, and extracted from, deep arrays
|
||||||
|
* and JSON-serialized strings. Say, for example, that you have this array as an input:
|
||||||
|
*
|
||||||
|
* <pre><code>['foo' => ['bar' => ['baz' => 'some_value']]]</code></pre>
|
||||||
|
*
|
||||||
|
* and you wanted to insert or extract an element. Usually, you would use:
|
||||||
|
*
|
||||||
|
* <pre><code>$array['foo']['bar']['baz'] = 'new_value';</code></pre>
|
||||||
|
*
|
||||||
|
* but sometimes you do not have access to the variable - so a string representation is needed. Using
|
||||||
|
* XPath-like syntax, this class allows you to do this:
|
||||||
|
*
|
||||||
|
* <pre><code>$jsonPath = new JsonPath($array);
|
||||||
|
* $jsonPath->set('foo.bar.baz', 'new_value');
|
||||||
|
* $val = $jsonPath->get('foo.bar.baz');
|
||||||
|
* </code></pre>
|
||||||
|
*
|
||||||
|
* @package OpenCloud\Common
|
||||||
|
*/
|
||||||
|
class JsonPath
|
||||||
|
{
|
||||||
|
/** @var array */
|
||||||
|
private $jsonStructure;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $structure The initial data structure to extract from and insert into. Typically this will be a
|
||||||
|
* multidimensional associative array; but well-formed JSON strings are also acceptable.
|
||||||
|
*/
|
||||||
|
public function __construct($structure)
|
||||||
|
{
|
||||||
|
$this->jsonStructure = is_string($structure) ? json_decode($structure, true) : $structure;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a node in the structure
|
||||||
|
*
|
||||||
|
* @param $path The XPath to use
|
||||||
|
* @param $value The new value of the node
|
||||||
|
*/
|
||||||
|
public function set($path, $value)
|
||||||
|
{
|
||||||
|
$this->jsonStructure = $this->setPath($path, $value, $this->jsonStructure);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal method for recursive calls.
|
||||||
|
*
|
||||||
|
* @param $path
|
||||||
|
* @param $value
|
||||||
|
* @param $json
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
private function setPath($path, $value, $json)
|
||||||
|
{
|
||||||
|
$nodes = explode('.', $path);
|
||||||
|
$point = array_shift($nodes);
|
||||||
|
|
||||||
|
if (!isset($json[$point])) {
|
||||||
|
$json[$point] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($nodes)) {
|
||||||
|
$json[$point] = $this->setPath(implode('.', $nodes), $value, $json[$point]);
|
||||||
|
} else {
|
||||||
|
$json[$point] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $json;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the updated structure.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getStructure()
|
||||||
|
{
|
||||||
|
return $this->jsonStructure;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a path's value. If no path can be matched, NULL is returned.
|
||||||
|
*
|
||||||
|
* @param $path
|
||||||
|
* @return mixed|null
|
||||||
|
*/
|
||||||
|
public function get($path)
|
||||||
|
{
|
||||||
|
return $this->getPath($path, $this->jsonStructure);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal method for recursion.
|
||||||
|
*
|
||||||
|
* @param $path
|
||||||
|
* @param $json
|
||||||
|
* @return null
|
||||||
|
*/
|
||||||
|
private function getPath($path, $json)
|
||||||
|
{
|
||||||
|
$nodes = explode('.', $path);
|
||||||
|
$point = array_shift($nodes);
|
||||||
|
|
||||||
|
if (!isset($json[$point])) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($nodes)) {
|
||||||
|
return $json[$point];
|
||||||
|
} else {
|
||||||
|
return $this->getPath(implode('.', $nodes), $json[$point]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
115
server/vendor/php-opencloud/common/src/Common/JsonSchema/JsonPatch.php
vendored
Normal file
115
server/vendor/php-opencloud/common/src/Common/JsonSchema/JsonPatch.php
vendored
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\JsonSchema;
|
||||||
|
|
||||||
|
class JsonPatch
|
||||||
|
{
|
||||||
|
const OP_ADD = 'add';
|
||||||
|
const OP_REPLACE = 'replace';
|
||||||
|
const OP_REMOVE = 'remove';
|
||||||
|
|
||||||
|
public static function diff($src, $dest)
|
||||||
|
{
|
||||||
|
return (new static)->makeDiff($src, $dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function makeDiff($srcStruct, $desStruct, $path = '')
|
||||||
|
{
|
||||||
|
$changes = [];
|
||||||
|
|
||||||
|
if (is_object($srcStruct)) {
|
||||||
|
$changes = $this->handleObject($srcStruct, $desStruct, $path);
|
||||||
|
} elseif (is_array($srcStruct)) {
|
||||||
|
$changes = $this->handleArray($srcStruct, $desStruct, $path);
|
||||||
|
} elseif ($srcStruct != $desStruct) {
|
||||||
|
$changes[] = $this->makePatch(self::OP_REPLACE, $path, $desStruct);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function handleArray($srcStruct, $desStruct, $path)
|
||||||
|
{
|
||||||
|
$changes = [];
|
||||||
|
|
||||||
|
if ($diff = $this->arrayDiff($desStruct, $srcStruct)) {
|
||||||
|
foreach ($diff as $key => $val) {
|
||||||
|
if (is_object($val)) {
|
||||||
|
$changes = array_merge($changes, $this->makeDiff($srcStruct[$key], $val, $this->path($path, $key)));
|
||||||
|
} else {
|
||||||
|
$op = array_key_exists($key, $srcStruct) && !in_array($srcStruct[$key], $desStruct, true)
|
||||||
|
? self::OP_REPLACE : self::OP_ADD;
|
||||||
|
$changes[] = $this->makePatch($op, $this->path($path, $key), $val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} elseif ($srcStruct != $desStruct) {
|
||||||
|
foreach ($srcStruct as $key => $val) {
|
||||||
|
if (!in_array($val, $desStruct, true)) {
|
||||||
|
$changes[] = $this->makePatch(self::OP_REMOVE, $this->path($path, $key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function handleObject($srcStruct, $desStruct, $path)
|
||||||
|
{
|
||||||
|
$changes = [];
|
||||||
|
|
||||||
|
if ($this->shouldPartiallyReplace($srcStruct, $desStruct)) {
|
||||||
|
foreach ($desStruct as $key => $val) {
|
||||||
|
if (!property_exists($srcStruct, $key)) {
|
||||||
|
$changes[] = $this->makePatch(self::OP_ADD, $this->path($path, $key), $val);
|
||||||
|
} elseif ($srcStruct->$key != $val) {
|
||||||
|
$changes = array_merge($changes, $this->makeDiff($srcStruct->$key, $val, $this->path($path, $key)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} elseif ($this->shouldPartiallyReplace($desStruct, $srcStruct)) {
|
||||||
|
foreach ($srcStruct as $key => $val) {
|
||||||
|
if (!property_exists($desStruct, $key)) {
|
||||||
|
$changes[] = $this->makePatch(self::OP_REMOVE, $this->path($path, $key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function shouldPartiallyReplace($o1, $o2)
|
||||||
|
{
|
||||||
|
return count(array_diff_key((array) $o1, (array) $o2)) < count($o1);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function arrayDiff(array $a1, array $a2)
|
||||||
|
{
|
||||||
|
$result = [];
|
||||||
|
|
||||||
|
foreach ($a1 as $key => $val) {
|
||||||
|
if (!in_array($val, $a2, true)) {
|
||||||
|
$result[$key] = $val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function path($root, $path)
|
||||||
|
{
|
||||||
|
if ($path === '_empty_') {
|
||||||
|
$path = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return rtrim($root, '/') . '/' . ltrim($path, '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function makePatch($op, $path, $val = null)
|
||||||
|
{
|
||||||
|
switch ($op) {
|
||||||
|
default:
|
||||||
|
return ['op' => $op, 'path' => $path, 'value' => $val];
|
||||||
|
case self::OP_REMOVE:
|
||||||
|
return ['op' => $op, 'path' => $path];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
72
server/vendor/php-opencloud/common/src/Common/JsonSchema/Schema.php
vendored
Normal file
72
server/vendor/php-opencloud/common/src/Common/JsonSchema/Schema.php
vendored
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\JsonSchema;
|
||||||
|
|
||||||
|
use JsonSchema\Validator;
|
||||||
|
|
||||||
|
class Schema
|
||||||
|
{
|
||||||
|
private $body;
|
||||||
|
private $validator;
|
||||||
|
|
||||||
|
public function __construct($body, Validator $validator = null)
|
||||||
|
{
|
||||||
|
$this->body = (object) $body;
|
||||||
|
$this->validator = $validator ?: new Validator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPropertyPaths()
|
||||||
|
{
|
||||||
|
$paths = [];
|
||||||
|
|
||||||
|
foreach ($this->body->properties as $propertyName => $property) {
|
||||||
|
$paths[] = sprintf("/%s", $propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function normalizeObject($subject, array $aliases)
|
||||||
|
{
|
||||||
|
$out = new \stdClass;
|
||||||
|
|
||||||
|
foreach ($this->body->properties as $propertyName => $property) {
|
||||||
|
$name = isset($aliases[$propertyName]) ? $aliases[$propertyName] : $propertyName;
|
||||||
|
if (isset($property->readOnly) && $property->readOnly === true) {
|
||||||
|
continue;
|
||||||
|
} elseif (property_exists($subject, $name)) {
|
||||||
|
$out->$propertyName = $subject->$name;
|
||||||
|
} elseif (property_exists($subject, $propertyName)) {
|
||||||
|
$out->$propertyName = $subject->$propertyName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function validate($data)
|
||||||
|
{
|
||||||
|
$this->validator->check($data, $this->body);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isValid()
|
||||||
|
{
|
||||||
|
return $this->validator->isValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getErrors()
|
||||||
|
{
|
||||||
|
return $this->validator->getErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getErrorString()
|
||||||
|
{
|
||||||
|
$msg = "Provided values do not validate. Errors:\n";
|
||||||
|
|
||||||
|
foreach ($this->getErrors() as $error) {
|
||||||
|
$msg .= sprintf("[%s] %s\n", $error['property'], $error['message']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $msg;
|
||||||
|
}
|
||||||
|
}
|
243
server/vendor/php-opencloud/common/src/Common/Resource/AbstractResource.php
vendored
Normal file
243
server/vendor/php-opencloud/common/src/Common/Resource/AbstractResource.php
vendored
Normal file
|
@ -0,0 +1,243 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Resource;
|
||||||
|
|
||||||
|
use OpenCloud\Common\Api\Operator;
|
||||||
|
use OpenCloud\Common\Transport\Utils;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a top-level abstraction of a remote API resource. Usually a resource represents a discrete
|
||||||
|
* entity such as a Server, Container, Load Balancer. Apart from a representation of state, a resource can
|
||||||
|
* also execute RESTFul operations on itself (updating, deleting, listing) or on other models.
|
||||||
|
*
|
||||||
|
* @package OpenCloud\Common\Resource
|
||||||
|
*/
|
||||||
|
abstract class AbstractResource extends Operator implements ResourceInterface
|
||||||
|
{
|
||||||
|
const DEFAULT_MARKER_KEY = 'id';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The JSON key that indicates how the API nests singular resources. For example, when
|
||||||
|
* performing a GET, it could respond with ``{"server": {"id": "12345"}}``. In this case,
|
||||||
|
* "server" is the resource key, since the essential state of the server is nested inside.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $resourceKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The key that indicates how the API nests resource collections. For example, when
|
||||||
|
* performing a GET, it could respond with ``{"servers": [{}, {}]}``. In this case, "servers"
|
||||||
|
* is the resources key, since the array of servers is nested inside.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $resourcesKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates which attribute of the current resource should be used for pagination markers.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $markerKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array of aliases that will be checked when the resource is being populated. For example,
|
||||||
|
*
|
||||||
|
* 'FOO_BAR' => 'fooBar'
|
||||||
|
*
|
||||||
|
* will extract FOO_BAR from the response, and save it as 'fooBar' in the resource.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $aliases = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populates the current resource from a response object.
|
||||||
|
*
|
||||||
|
* @param ResponseInterface $response
|
||||||
|
*
|
||||||
|
* @return $this|ResourceInterface
|
||||||
|
*/
|
||||||
|
public function populateFromResponse(ResponseInterface $response)
|
||||||
|
{
|
||||||
|
if (strpos($response->getHeaderLine('Content-Type'), 'application/json') === 0) {
|
||||||
|
$json = Utils::jsonDecode($response);
|
||||||
|
if (!empty($json)) {
|
||||||
|
$this->populateFromArray(Utils::flattenJson($json, $this->resourceKey));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populates the current resource from a data array.
|
||||||
|
*
|
||||||
|
* @param array $array
|
||||||
|
*
|
||||||
|
* @return mixed|void
|
||||||
|
*/
|
||||||
|
public function populateFromArray(array $array)
|
||||||
|
{
|
||||||
|
$reflClass = new \ReflectionClass($this);
|
||||||
|
|
||||||
|
foreach ($array as $key => $val) {
|
||||||
|
$propertyName = isset($this->aliases[$key]) ? $this->aliases[$key] : $key;
|
||||||
|
|
||||||
|
if (property_exists($this, $propertyName)) {
|
||||||
|
if ($type = $this->extractTypeFromDocBlock($reflClass, $propertyName)) {
|
||||||
|
$val = $this->parseDocBlockValue($type, $val);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->$propertyName = $val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function parseDocBlockValue($type, $val)
|
||||||
|
{
|
||||||
|
if (strpos($type, '[]') === 0 && is_array($val)) {
|
||||||
|
$array = [];
|
||||||
|
foreach ($val as $subVal) {
|
||||||
|
$array[] = $this->model($this->normalizeModelClass(substr($type, 2)), $subVal);
|
||||||
|
}
|
||||||
|
$val = $array;
|
||||||
|
} elseif (strcasecmp($type, '\datetimeimmutable') === 0) {
|
||||||
|
$val = new \DateTimeImmutable($val);
|
||||||
|
} elseif ($this->isNotNativeType($type)) {
|
||||||
|
$val = $this->model($this->normalizeModelClass($type), $val);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $val;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function isNotNativeType($type)
|
||||||
|
{
|
||||||
|
return !in_array($type, [
|
||||||
|
'string', 'bool', 'boolean', 'double', 'null', 'array', 'object', 'int', 'integer', 'float', 'numeric',
|
||||||
|
'mixed'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function normalizeModelClass($class)
|
||||||
|
{
|
||||||
|
if (strpos($class, '\\') === false) {
|
||||||
|
$currentNamespace = (new \ReflectionClass($this))->getNamespaceName();
|
||||||
|
$class = sprintf("%s\\%s", $currentNamespace, $class);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $class;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function extractTypeFromDocBlock(\ReflectionClass $reflClass, $propertyName)
|
||||||
|
{
|
||||||
|
$docComment = $reflClass->getProperty($propertyName)->getDocComment();
|
||||||
|
|
||||||
|
if (!$docComment) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$matches = [];
|
||||||
|
preg_match('#@var ((\[\])?[\w|\\\]+)#', $docComment, $matches);
|
||||||
|
return isset($matches[1]) ? $matches[1] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal method which retrieves the values of provided keys.
|
||||||
|
*
|
||||||
|
* @param array $keys
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function getAttrs(array $keys)
|
||||||
|
{
|
||||||
|
$output = [];
|
||||||
|
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
if (property_exists($this, $key) && $this->$key !== null) {
|
||||||
|
$output[$key] = $this->$key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $definition
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function executeWithState(array $definition)
|
||||||
|
{
|
||||||
|
return $this->execute($definition, $this->getAttrs(array_keys($definition['params'])));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getResourcesKey()
|
||||||
|
{
|
||||||
|
$resourcesKey = $this->resourcesKey;
|
||||||
|
|
||||||
|
if (!$resourcesKey) {
|
||||||
|
$class = substr(static::class, strrpos(static::class, '\\') + 1);
|
||||||
|
$resourcesKey = strtolower(preg_replace('/([a-z])([A-Z])/', '$1_$2', $class)) . 's';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $resourcesKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function enumerate(array $def, array $userVals = [], callable $mapFn = null)
|
||||||
|
{
|
||||||
|
$operation = $this->getOperation($def);
|
||||||
|
|
||||||
|
$requestFn = function ($marker) use ($operation, $userVals) {
|
||||||
|
if ($marker) {
|
||||||
|
$userVals['marker'] = $marker;
|
||||||
|
}
|
||||||
|
return $this->sendRequest($operation, $userVals);
|
||||||
|
};
|
||||||
|
|
||||||
|
$resourceFn = function (array $data) {
|
||||||
|
$resource = $this->newInstance();
|
||||||
|
$resource->populateFromArray($data);
|
||||||
|
return $resource;
|
||||||
|
};
|
||||||
|
|
||||||
|
$opts = [
|
||||||
|
'limit' => isset($userVals['limit']) ? $userVals['limit'] : null,
|
||||||
|
'resourcesKey' => $this->getResourcesKey(),
|
||||||
|
'markerKey' => $this->markerKey,
|
||||||
|
'mapFn' => $mapFn,
|
||||||
|
];
|
||||||
|
|
||||||
|
$iterator = new Iterator($opts, $requestFn, $resourceFn);
|
||||||
|
return $iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function extractMultipleInstances(ResponseInterface $response, $key = null)
|
||||||
|
{
|
||||||
|
$key = $key ?: $this->getResourcesKey();
|
||||||
|
$resourcesData = Utils::jsonDecode($response)[$key];
|
||||||
|
|
||||||
|
$resources = [];
|
||||||
|
|
||||||
|
foreach ($resourcesData as $resourceData) {
|
||||||
|
$resource = $this->newInstance();
|
||||||
|
$resource->populateFromArray($resourceData);
|
||||||
|
$resources[] = $resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $resources;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getService()
|
||||||
|
{
|
||||||
|
$class = static::class;
|
||||||
|
$service = substr($class, 0, strpos($class, 'Models') - 1) . '\\Service';
|
||||||
|
|
||||||
|
return new $service($this->client, $this->api);
|
||||||
|
}
|
||||||
|
}
|
19
server/vendor/php-opencloud/common/src/Common/Resource/Creatable.php
vendored
Normal file
19
server/vendor/php-opencloud/common/src/Common/Resource/Creatable.php
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a resource that can be created.
|
||||||
|
*
|
||||||
|
* @package OpenCloud\Common\Resource
|
||||||
|
*/
|
||||||
|
interface Creatable
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create a new resource according to the configuration set in the options.
|
||||||
|
*
|
||||||
|
* @param array $userOptions
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function create(array $userOptions);
|
||||||
|
}
|
18
server/vendor/php-opencloud/common/src/Common/Resource/Deletable.php
vendored
Normal file
18
server/vendor/php-opencloud/common/src/Common/Resource/Deletable.php
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a resource that can be deleted.
|
||||||
|
*
|
||||||
|
* @package OpenCloud\Common\Resource
|
||||||
|
*/
|
||||||
|
interface Deletable
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Permanently delete this resource.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function delete();
|
||||||
|
}
|
67
server/vendor/php-opencloud/common/src/Common/Resource/HasMetadata.php
vendored
Normal file
67
server/vendor/php-opencloud/common/src/Common/Resource/HasMetadata.php
vendored
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Resource;
|
||||||
|
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
|
||||||
|
interface HasMetadata
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Retrieves the metadata for the resource in the form of an associative array or hash. Each key represents the
|
||||||
|
* metadata item's name, and each value represents the metadata item's remote value.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getMetadata();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merges a set of new values with those which already exist (on the remote API) for a resource. For example, if
|
||||||
|
* the resource has this metadata already set:
|
||||||
|
*
|
||||||
|
* Foo: val1
|
||||||
|
* Bar: val2
|
||||||
|
*
|
||||||
|
* and mergeMetadata(['Foo' => 'val3', 'Baz' => 'val4']); is called, then the resource will have the following
|
||||||
|
* metadata:
|
||||||
|
*
|
||||||
|
* Foo: val3
|
||||||
|
* Bar: val2
|
||||||
|
* Baz: val4
|
||||||
|
*
|
||||||
|
* You will notice that any metadata items which are not specified in the call are preserved.
|
||||||
|
*
|
||||||
|
* @param array $metadata The new metadata items
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function mergeMetadata(array $metadata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces all of the existing metadata items for a resource with a new set of values. Any metadata items which
|
||||||
|
* are not provided in the call are removed from the resource. For example, if the resource has this metadata
|
||||||
|
* already set:
|
||||||
|
*
|
||||||
|
* Foo: val1
|
||||||
|
* Bar: val2
|
||||||
|
*
|
||||||
|
* and resetMetadata(['Foo' => 'val3', 'Baz' => 'val4']); is called, then the resource will have the following
|
||||||
|
* metadata:
|
||||||
|
*
|
||||||
|
* Foo: val3
|
||||||
|
* Baz: val4
|
||||||
|
*
|
||||||
|
* @param array $metadata The new metadata items
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function resetMetadata(array $metadata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts metadata from a response object and returns it in the form of an associative array.
|
||||||
|
*
|
||||||
|
* @param ResponseInterface $response
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function parseMetadata(ResponseInterface $response);
|
||||||
|
}
|
124
server/vendor/php-opencloud/common/src/Common/Resource/HasWaiterTrait.php
vendored
Normal file
124
server/vendor/php-opencloud/common/src/Common/Resource/HasWaiterTrait.php
vendored
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Resource;
|
||||||
|
|
||||||
|
use OpenCloud\Common\Error\BadResponseError;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains reusable functionality for resources that have long operations which require waiting in
|
||||||
|
* order to reach a particular state.
|
||||||
|
*
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*
|
||||||
|
* @package OpenCloud\Common\Resource
|
||||||
|
*/
|
||||||
|
trait HasWaiterTrait
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Provides a blocking operation until the resource has reached a particular state. The method
|
||||||
|
* will enter a loop, requesting feedback from the remote API until it sends back an appropriate
|
||||||
|
* status.
|
||||||
|
*
|
||||||
|
* @param string $status The state to be reached
|
||||||
|
* @param int $timeout The maximum timeout. If the total time taken by the waiter has reached
|
||||||
|
* or exceed this timeout, the blocking operation will immediately cease.
|
||||||
|
* @param int $sleepPeriod The amount of time to pause between each HTTP request.
|
||||||
|
*/
|
||||||
|
public function waitUntil($status, $timeout = 60, $sleepPeriod = 1)
|
||||||
|
{
|
||||||
|
$startTime = time();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
$this->retrieve();
|
||||||
|
|
||||||
|
if ($this->status == $status || $this->shouldHalt($timeout, $startTime)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep($sleepPeriod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a blocking operation until the resource has reached a particular state. The method
|
||||||
|
* will enter a loop, executing the callback until TRUE is returned. This provides great
|
||||||
|
* flexibility.
|
||||||
|
*
|
||||||
|
* @param callable $fn An anonymous function that will be executed on every iteration. You can
|
||||||
|
* encapsulate your own logic to determine whether the resource has
|
||||||
|
* successfully transitioned. When TRUE is returned by the callback,
|
||||||
|
* the loop will end.
|
||||||
|
* @param int|bool $timeout The maximum timeout in seconds. If the total time taken by the waiter has reached
|
||||||
|
* or exceed this timeout, the blocking operation will immediately cease. If FALSE
|
||||||
|
* is provided, the timeout will never be considered.
|
||||||
|
* @param int $sleepPeriod The amount of time to pause between each HTTP request.
|
||||||
|
*/
|
||||||
|
public function waitWithCallback(callable $fn, $timeout = 60, $sleepPeriod = 1)
|
||||||
|
{
|
||||||
|
$startTime = time();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
$this->retrieve();
|
||||||
|
|
||||||
|
$response = call_user_func_array($fn, [$this]);
|
||||||
|
|
||||||
|
if ($response === true || $this->shouldHalt($timeout, $startTime)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep($sleepPeriod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal method used to identify whether a timeout has been exceeded.
|
||||||
|
*
|
||||||
|
* @param bool|int $timeout
|
||||||
|
* @param int $startTime
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function shouldHalt($timeout, $startTime)
|
||||||
|
{
|
||||||
|
if ($timeout === false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return time() - $startTime >= $timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience method providing a blocking operation until the resource transitions to an
|
||||||
|
* ``ACTIVE`` status.
|
||||||
|
*
|
||||||
|
* @param int|bool $timeout The maximum timeout in seconds. If the total time taken by the waiter has reached
|
||||||
|
* or exceed this timeout, the blocking operation will immediately cease. If FALSE
|
||||||
|
* is provided, the timeout will never be considered.
|
||||||
|
*/
|
||||||
|
public function waitUntilActive($timeout = false)
|
||||||
|
{
|
||||||
|
$this->waitUntil('ACTIVE', $timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function waitUntilDeleted($timeout = 60, $sleepPeriod = 1)
|
||||||
|
{
|
||||||
|
$startTime = time();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
$this->retrieve();
|
||||||
|
} catch (BadResponseError $e) {
|
||||||
|
if ($e->getResponse()->getStatusCode() === 404) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->shouldHalt($timeout, $startTime)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep($sleepPeriod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
97
server/vendor/php-opencloud/common/src/Common/Resource/Iterator.php
vendored
Normal file
97
server/vendor/php-opencloud/common/src/Common/Resource/Iterator.php
vendored
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Resource;
|
||||||
|
|
||||||
|
use OpenCloud\Common\Transport\Utils;
|
||||||
|
|
||||||
|
class Iterator
|
||||||
|
{
|
||||||
|
private $requestFn;
|
||||||
|
private $resourceFn;
|
||||||
|
private $limit;
|
||||||
|
private $count;
|
||||||
|
private $resourcesKey;
|
||||||
|
private $markerKey;
|
||||||
|
private $mapFn;
|
||||||
|
private $currentMarker;
|
||||||
|
|
||||||
|
public function __construct(array $options, callable $requestFn, callable $resourceFn)
|
||||||
|
{
|
||||||
|
$this->limit = isset($options['limit']) ? $options['limit'] : false;
|
||||||
|
$this->count = 0;
|
||||||
|
|
||||||
|
if (isset($options['resourcesKey'])) {
|
||||||
|
$this->resourcesKey = $options['resourcesKey'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($options['markerKey'])) {
|
||||||
|
$this->markerKey = $options['markerKey'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($options['mapFn']) && is_callable($options['mapFn'])) {
|
||||||
|
$this->mapFn = $options['mapFn'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->requestFn = $requestFn;
|
||||||
|
$this->resourceFn = $resourceFn;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function fetchResources()
|
||||||
|
{
|
||||||
|
if ($this->shouldNotSendAnotherRequest()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = call_user_func($this->requestFn, $this->currentMarker);
|
||||||
|
|
||||||
|
$json = Utils::flattenJson(Utils::jsonDecode($response), $this->resourcesKey);
|
||||||
|
|
||||||
|
if ($response->getStatusCode() === 204 || empty($json)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $json;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function assembleResource(array $data)
|
||||||
|
{
|
||||||
|
$resource = call_user_func($this->resourceFn, $data);
|
||||||
|
|
||||||
|
// Invoke user-provided fn if provided
|
||||||
|
if ($this->mapFn) {
|
||||||
|
call_user_func_array($this->mapFn, [&$resource]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update marker if operation supports it
|
||||||
|
if ($this->markerKey) {
|
||||||
|
$this->currentMarker = $resource->{$this->markerKey};
|
||||||
|
}
|
||||||
|
|
||||||
|
return $resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function totalReached()
|
||||||
|
{
|
||||||
|
return $this->limit && $this->count >= $this->limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function shouldNotSendAnotherRequest()
|
||||||
|
{
|
||||||
|
return $this->totalReached() || ($this->count > 0 && !$this->markerKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __invoke()
|
||||||
|
{
|
||||||
|
while ($resources = $this->fetchResources()) {
|
||||||
|
foreach ($resources as $resourceData) {
|
||||||
|
if ($this->totalReached()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->count++;
|
||||||
|
|
||||||
|
yield $this->assembleResource($resourceData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
28
server/vendor/php-opencloud/common/src/Common/Resource/Listable.php
vendored
Normal file
28
server/vendor/php-opencloud/common/src/Common/Resource/Listable.php
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a resource that can be enumerated (listed over).
|
||||||
|
*
|
||||||
|
* @package OpenCloud\Common\Resource
|
||||||
|
*/
|
||||||
|
interface Listable
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* This method iterates over a collection of resources. It sends the operation's request to the API,
|
||||||
|
* parses the response, converts each element into {@see self} and - if pagination is supported - continues
|
||||||
|
* to send requests until an empty collection is received back.
|
||||||
|
*
|
||||||
|
* For paginated collections, it sends subsequent requests according to a marker URL query. The value
|
||||||
|
* of the marker will depend on the last element returned in the previous response. If a limit is
|
||||||
|
* provided, the loop will continue up until that point.
|
||||||
|
*
|
||||||
|
* @param array $def The operation definition
|
||||||
|
* @param array $userVals The user values
|
||||||
|
* @param callable $mapFn An optional callback that will be executed on every resource iteration.
|
||||||
|
*
|
||||||
|
* @returns void
|
||||||
|
*/
|
||||||
|
public function enumerate(array $def, array $userVals = [], callable $mapFn = null);
|
||||||
|
}
|
29
server/vendor/php-opencloud/common/src/Common/Resource/ResourceInterface.php
vendored
Normal file
29
server/vendor/php-opencloud/common/src/Common/Resource/ResourceInterface.php
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Resource;
|
||||||
|
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an API resource.
|
||||||
|
*
|
||||||
|
* @package OpenCloud\Common\Resource
|
||||||
|
*/
|
||||||
|
interface ResourceInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* All models which represent an API resource should be able to be populated
|
||||||
|
* from a {@see ResponseInterface} object.
|
||||||
|
*
|
||||||
|
* @param ResponseInterface $response
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function populateFromResponse(ResponseInterface $response);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function populateFromArray(array $data);
|
||||||
|
}
|
18
server/vendor/php-opencloud/common/src/Common/Resource/Retrievable.php
vendored
Normal file
18
server/vendor/php-opencloud/common/src/Common/Resource/Retrievable.php
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A resource that supports a GET or HEAD operation to retrieve more details.
|
||||||
|
*
|
||||||
|
* @package OpenCloud\Common\Resource
|
||||||
|
*/
|
||||||
|
interface Retrievable
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Retrieve details of the current resource from the remote API.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function retrieve();
|
||||||
|
}
|
18
server/vendor/php-opencloud/common/src/Common/Resource/Updateable.php
vendored
Normal file
18
server/vendor/php-opencloud/common/src/Common/Resource/Updateable.php
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a resource that can be updated.
|
||||||
|
*
|
||||||
|
* @package OpenCloud\Common\Resource
|
||||||
|
*/
|
||||||
|
interface Updateable
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Update the current resource with the configuration set out in the user options.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function update();
|
||||||
|
}
|
14
server/vendor/php-opencloud/common/src/Common/Service/AbstractService.php
vendored
Normal file
14
server/vendor/php-opencloud/common/src/Common/Service/AbstractService.php
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Service;
|
||||||
|
|
||||||
|
use OpenCloud\Common\Api\Operator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the top-level abstraction of a service.
|
||||||
|
*
|
||||||
|
* @package OpenCloud\Common\Service
|
||||||
|
*/
|
||||||
|
abstract class AbstractService extends Operator implements ServiceInterface
|
||||||
|
{
|
||||||
|
}
|
170
server/vendor/php-opencloud/common/src/Common/Service/Builder.php
vendored
Normal file
170
server/vendor/php-opencloud/common/src/Common/Service/Builder.php
vendored
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Service;
|
||||||
|
|
||||||
|
use GuzzleHttp\Client;
|
||||||
|
use GuzzleHttp\ClientInterface;
|
||||||
|
use GuzzleHttp\Middleware as GuzzleMiddleware;
|
||||||
|
use OpenCloud\Common\Auth\Token;
|
||||||
|
use OpenCloud\Common\Transport\HandlerStack;
|
||||||
|
use OpenCloud\Common\Transport\Middleware;
|
||||||
|
use OpenCloud\Common\Transport\Utils;
|
||||||
|
use OpenCloud\Identity\v3\Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Builder for easily creating OpenCloud services.
|
||||||
|
*
|
||||||
|
* @package OpenCloud\Common\Service
|
||||||
|
*/
|
||||||
|
class Builder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Global options that will be applied to every service created by this builder.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $globalOptions = [];
|
||||||
|
|
||||||
|
/** @var string */
|
||||||
|
private $rootNamespace;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defaults that will be applied to options if no values are provided by the user.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $defaults = ['urlType' => 'publicURL'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $globalOptions Options that will be applied to every service created by this builder.
|
||||||
|
* Eventually they will be merged (and if necessary overridden) by the
|
||||||
|
* service-specific options passed in.
|
||||||
|
*/
|
||||||
|
public function __construct(array $globalOptions = [], $rootNamespace = 'OpenCloud')
|
||||||
|
{
|
||||||
|
$this->globalOptions = $globalOptions;
|
||||||
|
$this->rootNamespace = $rootNamespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal method which resolves the API and Service classes for a service.
|
||||||
|
*
|
||||||
|
* @param string $serviceName The name of the service, e.g. Compute
|
||||||
|
* @param int $serviceVersion The major version of the service, e.g. 2
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function getClasses($serviceName, $serviceVersion)
|
||||||
|
{
|
||||||
|
$rootNamespace = sprintf("%s\\%s\\v%d", $this->rootNamespace, $serviceName, $serviceVersion);
|
||||||
|
|
||||||
|
return [
|
||||||
|
sprintf("%s\\Api", $rootNamespace),
|
||||||
|
sprintf("%s\\Service", $rootNamespace),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will return an OpenCloud service ready fully built and ready for use. There is
|
||||||
|
* some initial setup that may prohibit users from directly instantiating the service class
|
||||||
|
* directly - this setup includes the configuration of the HTTP client's base URL, and the
|
||||||
|
* attachment of an authentication handler.
|
||||||
|
*
|
||||||
|
* @param $serviceName The name of the service as it appears in the OpenCloud\* namespace
|
||||||
|
* @param $serviceVersion The major version of the service
|
||||||
|
* @param array $serviceOptions The service-specific options to use
|
||||||
|
*
|
||||||
|
* @return \OpenCloud\Common\Service\ServiceInterface
|
||||||
|
*
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function createService($serviceName, $serviceVersion, array $serviceOptions = [])
|
||||||
|
{
|
||||||
|
$options = $this->mergeOptions($serviceOptions);
|
||||||
|
|
||||||
|
$this->stockIdentityService($options);
|
||||||
|
$this->stockAuthHandler($options);
|
||||||
|
$this->stockHttpClient($options, $serviceName);
|
||||||
|
|
||||||
|
list($apiClass, $serviceClass) = $this->getClasses($serviceName, $serviceVersion);
|
||||||
|
|
||||||
|
return new $serviceClass($options['httpClient'], new $apiClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function stockHttpClient(array &$options, $serviceName)
|
||||||
|
{
|
||||||
|
if (!isset($options['httpClient']) || !($options['httpClient'] instanceof ClientInterface)) {
|
||||||
|
if (strcasecmp($serviceName, 'identity') === 0) {
|
||||||
|
$baseUrl = $options['authUrl'];
|
||||||
|
$stack = $this->getStack($options['authHandler']);
|
||||||
|
} else {
|
||||||
|
list($token, $baseUrl) = $options['identityService']->authenticate($options);
|
||||||
|
$stack = $this->getStack($options['authHandler'], $token);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->addDebugMiddleware($options, $stack);
|
||||||
|
|
||||||
|
$options['httpClient'] = $this->httpClient($baseUrl, $stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*/
|
||||||
|
private function addDebugMiddleware(array $options, HandlerStack &$stack)
|
||||||
|
{
|
||||||
|
if (!empty($options['debugLog'])
|
||||||
|
&& !empty($options['logger'])
|
||||||
|
&& !empty($options['messageFormatter'])
|
||||||
|
) {
|
||||||
|
$stack->push(GuzzleMiddleware::log($options['logger'], $options['messageFormatter']));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function stockIdentityService(array &$options)
|
||||||
|
{
|
||||||
|
if (!isset($options['identityService'])) {
|
||||||
|
$httpClient = $this->httpClient($options['authUrl'], HandlerStack::create());
|
||||||
|
$options['identityService'] = Service::factory($httpClient);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $options
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*/
|
||||||
|
private function stockAuthHandler(array &$options)
|
||||||
|
{
|
||||||
|
if (!isset($options['authHandler'])) {
|
||||||
|
$options['authHandler'] = function () use ($options) {
|
||||||
|
return $options['identityService']->generateToken($options);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getStack(callable $authHandler, Token $token = null)
|
||||||
|
{
|
||||||
|
$stack = HandlerStack::create();
|
||||||
|
$stack->push(Middleware::authHandler($authHandler, $token));
|
||||||
|
return $stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function httpClient($baseUrl, HandlerStack $stack)
|
||||||
|
{
|
||||||
|
return new Client([
|
||||||
|
'base_uri' => Utils::normalizeUrl($baseUrl),
|
||||||
|
'handler' => $stack,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function mergeOptions(array $serviceOptions)
|
||||||
|
{
|
||||||
|
$options = array_merge($this->defaults, $this->globalOptions, $serviceOptions);
|
||||||
|
|
||||||
|
if (!isset($options['authUrl'])) {
|
||||||
|
throw new \InvalidArgumentException('"authUrl" is a required option');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $options;
|
||||||
|
}
|
||||||
|
}
|
14
server/vendor/php-opencloud/common/src/Common/Service/ServiceInterface.php
vendored
Normal file
14
server/vendor/php-opencloud/common/src/Common/Service/ServiceInterface.php
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Service;
|
||||||
|
|
||||||
|
use OpenCloud\Common\Api\OperatorInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service interface.
|
||||||
|
*
|
||||||
|
* @package OpenCloud\Common\Service
|
||||||
|
*/
|
||||||
|
interface ServiceInterface extends OperatorInterface
|
||||||
|
{
|
||||||
|
}
|
19
server/vendor/php-opencloud/common/src/Common/Transport/HandlerStack.php
vendored
Normal file
19
server/vendor/php-opencloud/common/src/Common/Transport/HandlerStack.php
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Transport;
|
||||||
|
|
||||||
|
use function GuzzleHttp\choose_handler;
|
||||||
|
use GuzzleHttp\HandlerStack as GuzzleStack;
|
||||||
|
|
||||||
|
class HandlerStack extends GuzzleStack
|
||||||
|
{
|
||||||
|
public static function create(callable $handler = null)
|
||||||
|
{
|
||||||
|
$stack = new self($handler ?: choose_handler());
|
||||||
|
|
||||||
|
$stack->push(Middleware::httpErrors());
|
||||||
|
$stack->push(Middleware::prepareBody());
|
||||||
|
|
||||||
|
return $stack;
|
||||||
|
}
|
||||||
|
}
|
95
server/vendor/php-opencloud/common/src/Common/Transport/JsonSerializer.php
vendored
Normal file
95
server/vendor/php-opencloud/common/src/Common/Transport/JsonSerializer.php
vendored
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Transport;
|
||||||
|
|
||||||
|
use OpenCloud\Common\Api\Parameter;
|
||||||
|
use OpenCloud\Common\JsonPath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class responsible for populating the JSON body of a {@see GuzzleHttp\Message\Request} object.
|
||||||
|
*
|
||||||
|
* @package OpenCloud\Common\Transport
|
||||||
|
*/
|
||||||
|
class JsonSerializer
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Populates the actual value into a JSON field, i.e. it has reached the end of the line and no
|
||||||
|
* further nesting is required.
|
||||||
|
*
|
||||||
|
* @param Parameter $param The schema that defines how the JSON field is being populated
|
||||||
|
* @param mixed $userValue The user value that is populating a JSON field
|
||||||
|
* @param array $json The existing JSON structure that will be populated
|
||||||
|
*
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
private function stockValue(Parameter $param, $userValue, $json)
|
||||||
|
{
|
||||||
|
$name = $param->getName();
|
||||||
|
if ($path = $param->getPath()) {
|
||||||
|
$jsonPath = new JsonPath($json);
|
||||||
|
$jsonPath->set(sprintf("%s.%s", $path, $name), $userValue);
|
||||||
|
$json = $jsonPath->getStructure();
|
||||||
|
} elseif ($name) {
|
||||||
|
$json[$name] = $userValue;
|
||||||
|
} else {
|
||||||
|
$json[] = $userValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $json;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populates a value into an array-like structure.
|
||||||
|
*
|
||||||
|
* @param Parameter $param The schema that defines how the JSON field is being populated
|
||||||
|
* @param mixed $userValue The user value that is populating a JSON field
|
||||||
|
*
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
private function stockArrayJson(Parameter $param, $userValue)
|
||||||
|
{
|
||||||
|
$elems = [];
|
||||||
|
foreach ($userValue as $item) {
|
||||||
|
$elems = $this->stockJson($param->getItemSchema(), $item, $elems);
|
||||||
|
}
|
||||||
|
return $elems;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populates a value into an object-like structure.
|
||||||
|
*
|
||||||
|
* @param Parameter $param The schema that defines how the JSON field is being populated
|
||||||
|
* @param mixed $userValue The user value that is populating a JSON field
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function stockObjectJson(Parameter $param, $userValue)
|
||||||
|
{
|
||||||
|
$object = [];
|
||||||
|
foreach ($userValue as $key => $val) {
|
||||||
|
$object = $this->stockJson($param->getProperty($key), $val, $object);
|
||||||
|
}
|
||||||
|
return $object;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A generic method that will populate a JSON structure with a value according to a schema. It
|
||||||
|
* supports multiple types and will delegate accordingly.
|
||||||
|
*
|
||||||
|
* @param Parameter $param The schema that defines how the JSON field is being populated
|
||||||
|
* @param mixed $userValue The user value that is populating a JSON field
|
||||||
|
* @param array $json The existing JSON structure that will be populated
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function stockJson(Parameter $param, $userValue, $json)
|
||||||
|
{
|
||||||
|
if ($param->isArray()) {
|
||||||
|
$userValue = $this->stockArrayJson($param, $userValue);
|
||||||
|
} elseif ($param->isObject()) {
|
||||||
|
$userValue = $this->stockObjectJson($param, $userValue);
|
||||||
|
}
|
||||||
|
// Populate the final value
|
||||||
|
return $this->stockValue($param, $userValue, $json);
|
||||||
|
}
|
||||||
|
}
|
94
server/vendor/php-opencloud/common/src/Common/Transport/Middleware.php
vendored
Normal file
94
server/vendor/php-opencloud/common/src/Common/Transport/Middleware.php
vendored
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Transport;
|
||||||
|
|
||||||
|
use function GuzzleHttp\Psr7\modify_request;
|
||||||
|
use GuzzleHttp\MessageFormatter;
|
||||||
|
use GuzzleHttp\Middleware as GuzzleMiddleware;
|
||||||
|
use OpenCloud\Common\Auth\AuthHandler;
|
||||||
|
use OpenCloud\Common\Auth\Token;
|
||||||
|
use OpenCloud\Common\Error\Builder;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
|
||||||
|
final class Middleware
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return callable
|
||||||
|
*/
|
||||||
|
public static function httpErrors()
|
||||||
|
{
|
||||||
|
return function (callable $handler) {
|
||||||
|
return function ($request, array $options) use ($handler) {
|
||||||
|
return $handler($request, $options)->then(
|
||||||
|
function (ResponseInterface $response) use ($request, $handler) {
|
||||||
|
if ($response->getStatusCode() < 400) {
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
throw (new Builder())->httpError($request, $response);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param callable $tokenGenerator
|
||||||
|
* @param Token $token
|
||||||
|
*
|
||||||
|
* @return callable
|
||||||
|
*/
|
||||||
|
public static function authHandler(callable $tokenGenerator, Token $token = null)
|
||||||
|
{
|
||||||
|
return function (callable $handler) use ($tokenGenerator, $token) {
|
||||||
|
return new AuthHandler($handler, $tokenGenerator, $token);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*/
|
||||||
|
public static function history(array &$container)
|
||||||
|
{
|
||||||
|
return GuzzleMiddleware::history($container);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*/
|
||||||
|
public static function retry(callable $decider, callable $delay = null)
|
||||||
|
{
|
||||||
|
return GuzzleMiddleware::retry($decider, $delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*/
|
||||||
|
public static function log(LoggerInterface $logger, MessageFormatter $formatter, $logLevel = LogLevel::INFO)
|
||||||
|
{
|
||||||
|
return GuzzleMiddleware::log($logger, $formatter, $logLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*/
|
||||||
|
public static function prepareBody()
|
||||||
|
{
|
||||||
|
return GuzzleMiddleware::prepareBody();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*/
|
||||||
|
public static function mapRequest(callable $fn)
|
||||||
|
{
|
||||||
|
return GuzzleMiddleware::mapRequest($fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*/
|
||||||
|
public static function mapResponse(callable $fn)
|
||||||
|
{
|
||||||
|
return GuzzleMiddleware::mapResponse($fn);
|
||||||
|
}
|
||||||
|
}
|
85
server/vendor/php-opencloud/common/src/Common/Transport/RequestSerializer.php
vendored
Normal file
85
server/vendor/php-opencloud/common/src/Common/Transport/RequestSerializer.php
vendored
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Transport;
|
||||||
|
|
||||||
|
use function GuzzleHttp\uri_template;
|
||||||
|
use function GuzzleHttp\Psr7\build_query;
|
||||||
|
use function GuzzleHttp\Psr7\modify_request;
|
||||||
|
use OpenCloud\Common\Api\Operation;
|
||||||
|
use OpenCloud\Common\Api\Parameter;
|
||||||
|
|
||||||
|
class RequestSerializer
|
||||||
|
{
|
||||||
|
private $jsonSerializer;
|
||||||
|
|
||||||
|
public function __construct(JsonSerializer $jsonSerializer = null)
|
||||||
|
{
|
||||||
|
$this->jsonSerializer = $jsonSerializer ?: new JsonSerializer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function serializeOptions(Operation $operation, array $userValues = [])
|
||||||
|
{
|
||||||
|
$options = ['headers' => []];
|
||||||
|
|
||||||
|
foreach ($userValues as $paramName => $paramValue) {
|
||||||
|
if (null === ($schema = $operation->getParam($paramName))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$method = sprintf('stock%s', ucfirst($schema->getLocation()));
|
||||||
|
$this->$method($schema, $paramValue, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($options['json'])) {
|
||||||
|
if ($key = $operation->getJsonKey()) {
|
||||||
|
$options['json'] = [$key => $options['json']];
|
||||||
|
}
|
||||||
|
if (strpos(json_encode($options['json']), '\/') !== false) {
|
||||||
|
$options['body'] = json_encode($options['json'], JSON_UNESCAPED_SLASHES);
|
||||||
|
$options['headers']['Content-Type'] = 'application/json';
|
||||||
|
unset($options['json']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $options;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function stockUrl()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private function stockQuery(Parameter $schema, $paramValue, array &$options)
|
||||||
|
{
|
||||||
|
$options['query'][$schema->getName()] = $paramValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function stockHeader(Parameter $schema, $paramValue, array &$options)
|
||||||
|
{
|
||||||
|
$paramName = $schema->getName();
|
||||||
|
|
||||||
|
if (stripos($paramName, 'metadata') !== false) {
|
||||||
|
return $this->stockMetadataHeader($schema, $paramValue, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
$options['headers'] += is_scalar($paramValue) ? [$schema->getPrefixedName() => $paramValue] : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function stockMetadataHeader(Parameter $schema, $paramValue, array &$options)
|
||||||
|
{
|
||||||
|
foreach ($paramValue as $key => $keyVal) {
|
||||||
|
$schema = $schema->getItemSchema() ?: new Parameter(['prefix' => $schema->getPrefix(), 'name' => $key]);
|
||||||
|
$this->stockHeader($schema, $keyVal, $options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function stockJson(Parameter $schema, $paramValue, array &$options)
|
||||||
|
{
|
||||||
|
$json = isset($options['json']) ? $options['json'] : [];
|
||||||
|
$options['json'] = $this->jsonSerializer->stockJson($schema, $paramValue, $json);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function stockRaw(Parameter $schema, $paramValue, array &$options)
|
||||||
|
{
|
||||||
|
$options['body'] = $paramValue;
|
||||||
|
}
|
||||||
|
}
|
88
server/vendor/php-opencloud/common/src/Common/Transport/Utils.php
vendored
Normal file
88
server/vendor/php-opencloud/common/src/Common/Transport/Utils.php
vendored
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\Common\Transport;
|
||||||
|
|
||||||
|
use function GuzzleHttp\Psr7\uri_for;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use Psr\Http\Message\UriInterface;
|
||||||
|
|
||||||
|
class Utils
|
||||||
|
{
|
||||||
|
public static function jsonDecode(ResponseInterface $response, $assoc = true)
|
||||||
|
{
|
||||||
|
$jsonErrors = [
|
||||||
|
JSON_ERROR_DEPTH => 'JSON_ERROR_DEPTH - Maximum stack depth exceeded',
|
||||||
|
JSON_ERROR_STATE_MISMATCH => 'JSON_ERROR_STATE_MISMATCH - Underflow or the modes mismatch',
|
||||||
|
JSON_ERROR_CTRL_CHAR => 'JSON_ERROR_CTRL_CHAR - Unexpected control character found',
|
||||||
|
JSON_ERROR_SYNTAX => 'JSON_ERROR_SYNTAX - Syntax error, malformed JSON',
|
||||||
|
JSON_ERROR_UTF8 => 'JSON_ERROR_UTF8 - Malformed UTF-8 characters, possibly incorrectly encoded'
|
||||||
|
];
|
||||||
|
|
||||||
|
$responseBody = (string) $response->getBody();
|
||||||
|
|
||||||
|
if (strlen($responseBody) === 0) {
|
||||||
|
return $responseBody;
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = json_decode($responseBody, $assoc);
|
||||||
|
|
||||||
|
if (JSON_ERROR_NONE !== json_last_error()) {
|
||||||
|
$last = json_last_error();
|
||||||
|
throw new \InvalidArgumentException(
|
||||||
|
'Unable to parse JSON data: ' . (isset($jsonErrors[$last]) ? $jsonErrors[$last] : 'Unknown error')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method for flattening a nested array.
|
||||||
|
*
|
||||||
|
* @param array $data The nested array
|
||||||
|
* @param null $key The key to extract
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function flattenJson($data, $key = null)
|
||||||
|
{
|
||||||
|
return (!empty($data) && $key && isset($data[$key])) ? $data[$key] : $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method for normalize an URL string.
|
||||||
|
*
|
||||||
|
* Append the http:// prefix if not present, and add a
|
||||||
|
* closing url separator when missing.
|
||||||
|
*
|
||||||
|
* @param string $url The url representation.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function normalizeUrl($url)
|
||||||
|
{
|
||||||
|
if (strpos($url, 'http') === false) {
|
||||||
|
$url = 'http://' . $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rtrim($url, '/') . '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an unlimited list of paths to a given URI.
|
||||||
|
*
|
||||||
|
* @param UriInterface $uri
|
||||||
|
* @param ...$paths
|
||||||
|
*
|
||||||
|
* @return UriInterface
|
||||||
|
*/
|
||||||
|
public static function addPaths(UriInterface $uri, ...$paths)
|
||||||
|
{
|
||||||
|
return uri_for(rtrim((string) $uri, '/') . '/' . implode('/', $paths));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function appendPath(UriInterface $uri, $path)
|
||||||
|
{
|
||||||
|
return uri_for(rtrim((string) $uri, '/') . '/' . $path);
|
||||||
|
}
|
||||||
|
}
|
20
server/vendor/php-opencloud/common/tests/integration/DefaultLogger.php
vendored
Normal file
20
server/vendor/php-opencloud/common/tests/integration/DefaultLogger.php
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\integration;
|
||||||
|
|
||||||
|
use Psr\Log\AbstractLogger;
|
||||||
|
|
||||||
|
class DefaultLogger extends AbstractLogger
|
||||||
|
{
|
||||||
|
public function log($level, $message, array $context = [])
|
||||||
|
{
|
||||||
|
echo $this->format($level, $message, $context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function format($level, $message, $context)
|
||||||
|
{
|
||||||
|
$msg = strtr($message, $context);
|
||||||
|
|
||||||
|
return sprintf("%s: %s\n", strtoupper($level), $msg);
|
||||||
|
}
|
||||||
|
}
|
112
server/vendor/php-opencloud/common/tests/integration/Runner.php
vendored
Normal file
112
server/vendor/php-opencloud/common/tests/integration/Runner.php
vendored
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\integration;
|
||||||
|
|
||||||
|
class Runner
|
||||||
|
{
|
||||||
|
private $basePath;
|
||||||
|
private $logger;
|
||||||
|
private $services = [];
|
||||||
|
|
||||||
|
public function __construct($basePath)
|
||||||
|
{
|
||||||
|
$this->basePath = $basePath;
|
||||||
|
$this->logger = new DefaultLogger();
|
||||||
|
$this->assembleServicesFromSamples();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function traverse($path)
|
||||||
|
{
|
||||||
|
return new \RecursiveDirectoryIterator($path, \FilesystemIterator::SKIP_DOTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function assembleServicesFromSamples()
|
||||||
|
{
|
||||||
|
foreach ($this->traverse($this->basePath) as $servicePath) {
|
||||||
|
if ($servicePath->isDir()) {
|
||||||
|
foreach ($this->traverse($servicePath) as $versionPath) {
|
||||||
|
$this->services[$servicePath->getBasename()][] = $versionPath->getBasename();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getOpts()
|
||||||
|
{
|
||||||
|
$opts = getopt('s:v:t:', ['service:', 'version:', 'test::', 'debug::', 'help::']);
|
||||||
|
|
||||||
|
$getOpt = function (array $keys, $default) use ($opts) {
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
if (isset($opts[$key])) {
|
||||||
|
return $opts[$key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $default;
|
||||||
|
};
|
||||||
|
|
||||||
|
return [
|
||||||
|
$getOpt(['s', 'service'], 'all'),
|
||||||
|
$getOpt(['n', 'version'], 'all'),
|
||||||
|
$getOpt(['t', 'test'], ''),
|
||||||
|
isset($opts['debug']) ? (int) $opts['debug'] : 0,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getRunnableServices($service, $version)
|
||||||
|
{
|
||||||
|
$services = $this->services;
|
||||||
|
|
||||||
|
if ($service != 'all') {
|
||||||
|
if (!isset($this->services[$service])) {
|
||||||
|
throw new \InvalidArgumentException(sprintf("%s service does not exist", $service));
|
||||||
|
}
|
||||||
|
|
||||||
|
$versions = ($version == 'all') ? $this->services[$service] : [$version];
|
||||||
|
$services = [$service => $versions];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $services;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return TestInterface
|
||||||
|
*/
|
||||||
|
private function getTest($serviceName, $version, $verbosity)
|
||||||
|
{
|
||||||
|
$namespace = (new \ReflectionClass($this))->getNamespaceName();
|
||||||
|
$className = sprintf("%s\\%s\\%sTest", $namespace, Utils::toCamelCase($serviceName), ucfirst($version));
|
||||||
|
|
||||||
|
if (!class_exists($className)) {
|
||||||
|
throw new \RuntimeException(sprintf("%s does not exist", $className));
|
||||||
|
}
|
||||||
|
|
||||||
|
$basePath = $this->basePath . DIRECTORY_SEPARATOR . $serviceName . DIRECTORY_SEPARATOR . $version;
|
||||||
|
$smClass = sprintf("%s\\SampleManager", $namespace);
|
||||||
|
$class = new $className($this->logger, new $smClass($basePath, $verbosity));
|
||||||
|
|
||||||
|
if (!($class instanceof TestInterface)) {
|
||||||
|
throw new \RuntimeException(sprintf("%s does not implement TestInterface", $className));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function runServices()
|
||||||
|
{
|
||||||
|
list($serviceOpt, $versionOpt, $testMethodOpt, $verbosityOpt) = $this->getOpts();
|
||||||
|
|
||||||
|
foreach ($this->getRunnableServices($serviceOpt, $versionOpt) as $serviceName => $versions) {
|
||||||
|
foreach ($versions as $version) {
|
||||||
|
$testRunner = $this->getTest($serviceName, $version, $verbosityOpt);
|
||||||
|
|
||||||
|
if ($testMethodOpt) {
|
||||||
|
$testRunner->runOneTest($testMethodOpt);
|
||||||
|
} else {
|
||||||
|
$testRunner->runTests();
|
||||||
|
}
|
||||||
|
|
||||||
|
$testRunner->teardown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
104
server/vendor/php-opencloud/common/tests/integration/SampleManager.php
vendored
Normal file
104
server/vendor/php-opencloud/common/tests/integration/SampleManager.php
vendored
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\integration;
|
||||||
|
|
||||||
|
class SampleManager implements SampleManagerInterface
|
||||||
|
{
|
||||||
|
protected $basePath;
|
||||||
|
protected $paths = [];
|
||||||
|
protected $verbosity;
|
||||||
|
|
||||||
|
public function __construct($basePath, $verbosity)
|
||||||
|
{
|
||||||
|
$this->basePath = $basePath;
|
||||||
|
$this->verbosity = $verbosity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deletePaths()
|
||||||
|
{
|
||||||
|
if (!empty($this->paths)) {
|
||||||
|
foreach ($this->paths as $path) {
|
||||||
|
unlink($path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getGlobalReplacements()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'{userId}' => getenv('OS_USER_ID'),
|
||||||
|
'{username}' => getenv('OS_USERNAME'),
|
||||||
|
'{password}' => getenv('OS_PASSWORD'),
|
||||||
|
'{domainId}' => getenv('OS_DOMAIN_ID'),
|
||||||
|
'{authUrl}' => getenv('OS_AUTH_URL'),
|
||||||
|
'{tenantId}' => getenv('OS_TENANT_ID'),
|
||||||
|
'{region}' => getenv('OS_REGION'),
|
||||||
|
'{projectId}' => getenv('OS_PROJECT_ID'),
|
||||||
|
'{projectName}' => getenv('OS_PROJECT_NAME'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getConnectionTemplate()
|
||||||
|
{
|
||||||
|
if ($this->verbosity === 1) {
|
||||||
|
$subst = <<<'EOL'
|
||||||
|
use OpenCloud\Integration\DefaultLogger;
|
||||||
|
use OpenCloud\Integration\Utils;
|
||||||
|
use GuzzleHttp\MessageFormatter;
|
||||||
|
|
||||||
|
$options = [
|
||||||
|
'debugLog' => true,
|
||||||
|
'logger' => new DefaultLogger(),
|
||||||
|
'messageFormatter' => new MessageFormatter(),
|
||||||
|
];
|
||||||
|
$openstack = new OpenCloud\OpenCloud(Utils::getAuthOpts($options));
|
||||||
|
EOL;
|
||||||
|
} elseif ($this->verbosity === 2) {
|
||||||
|
$subst = <<<'EOL'
|
||||||
|
use OpenCloud\Integration\DefaultLogger;
|
||||||
|
use OpenCloud\Integration\Utils;
|
||||||
|
use GuzzleHttp\MessageFormatter;
|
||||||
|
|
||||||
|
$options = [
|
||||||
|
'debugLog' => true,
|
||||||
|
'logger' => new DefaultLogger(),
|
||||||
|
'messageFormatter' => new MessageFormatter(MessageFormatter::DEBUG),
|
||||||
|
];
|
||||||
|
$openstack = new OpenCloud\OpenCloud(Utils::getAuthOpts($options));
|
||||||
|
EOL;
|
||||||
|
} else {
|
||||||
|
$subst = <<<'EOL'
|
||||||
|
use OpenCloud\Integration\Utils;
|
||||||
|
|
||||||
|
$openstack = new OpenCloud\OpenCloud(Utils::getAuthOpts());
|
||||||
|
EOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $subst;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function write($path, array $replacements)
|
||||||
|
{
|
||||||
|
$replacements = array_merge($this->getGlobalReplacements(), $replacements);
|
||||||
|
|
||||||
|
$sampleFile = rtrim($this->basePath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $path;
|
||||||
|
|
||||||
|
if (!file_exists($sampleFile) || !is_readable($sampleFile)) {
|
||||||
|
throw new \RuntimeException(sprintf("%s either does not exist or is not readable", $sampleFile));
|
||||||
|
}
|
||||||
|
|
||||||
|
$content = strtr(file_get_contents($sampleFile), $replacements);
|
||||||
|
$content = str_replace("'vendor/'", "'" . dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR . "vendor'", $content);
|
||||||
|
|
||||||
|
$subst = $this->getConnectionTemplate();
|
||||||
|
$content = preg_replace('/\([^)]+\)/', '', $content, 1);
|
||||||
|
$content = str_replace('$openstack = new OpenCloud\OpenCloud;', $subst, $content);
|
||||||
|
|
||||||
|
$tmp = tempnam(sys_get_temp_dir(), 'openstack');
|
||||||
|
file_put_contents($tmp, $content);
|
||||||
|
|
||||||
|
$this->paths[] = $tmp;
|
||||||
|
|
||||||
|
return $tmp;
|
||||||
|
}
|
||||||
|
}
|
10
server/vendor/php-opencloud/common/tests/integration/SampleManagerInterface.php
vendored
Normal file
10
server/vendor/php-opencloud/common/tests/integration/SampleManagerInterface.php
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\integration;
|
||||||
|
|
||||||
|
interface SampleManagerInterface
|
||||||
|
{
|
||||||
|
public function write($path, array $replacements);
|
||||||
|
|
||||||
|
public function deletePaths();
|
||||||
|
}
|
115
server/vendor/php-opencloud/common/tests/integration/TestCase.php
vendored
Normal file
115
server/vendor/php-opencloud/common/tests/integration/TestCase.php
vendored
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\integration;
|
||||||
|
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
|
abstract class TestCase extends \PHPUnit_Framework_TestCase implements TestInterface
|
||||||
|
{
|
||||||
|
private $logger;
|
||||||
|
private $startPoint;
|
||||||
|
private $lastPoint;
|
||||||
|
private $sampleManager;
|
||||||
|
|
||||||
|
public function __construct(LoggerInterface $logger, SampleManagerInterface $sampleManager)
|
||||||
|
{
|
||||||
|
$this->logger = $logger;
|
||||||
|
$this->sampleManager = $sampleManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function teardown()
|
||||||
|
{
|
||||||
|
$this->sampleManager->deletePaths();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function runOneTest($name)
|
||||||
|
{
|
||||||
|
if (!method_exists($this, $name)) {
|
||||||
|
throw new \InvalidArgumentException(sprintf("%s method does not exist", $name));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->startTimer();
|
||||||
|
$this->$name();
|
||||||
|
$this->outputTimeTaken();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function startTimer()
|
||||||
|
{
|
||||||
|
$this->startPoint = $this->lastPoint = microtime(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function wrapColor($message, $colorPrefix)
|
||||||
|
{
|
||||||
|
return sprintf("%s%s", $colorPrefix, $message) . "\033[0m\033[1;0m";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function logStep($message, array $context = [])
|
||||||
|
{
|
||||||
|
$duration = microtime(true) - $this->lastPoint;
|
||||||
|
|
||||||
|
$stepTimeTaken = sprintf('(%s)', $this->formatSecDifference($duration));
|
||||||
|
|
||||||
|
if ($duration >= 10) {
|
||||||
|
$color = "\033[0m\033[1;31m"; // red
|
||||||
|
} elseif ($duration >= 2) {
|
||||||
|
$color = "\033[0m\033[1;33m"; // yellow
|
||||||
|
} else {
|
||||||
|
$color = "\033[0m\033[1;32m"; // green
|
||||||
|
}
|
||||||
|
|
||||||
|
$message = '{timeTaken} ' . $message;
|
||||||
|
$context['{timeTaken}'] = $this->wrapColor($stepTimeTaken, $color);
|
||||||
|
|
||||||
|
$this->logger->info($message, $context);
|
||||||
|
|
||||||
|
$this->lastPoint = microtime(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function randomStr($length = 5)
|
||||||
|
{
|
||||||
|
$chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||||
|
$charsLen = strlen($chars);
|
||||||
|
|
||||||
|
$randomString = '';
|
||||||
|
for ($i = 0; $i < $length; $i++) {
|
||||||
|
$randomString .= $chars[rand(0, $charsLen - 1)];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'phptest_' . $randomString;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function formatMinDifference($duration)
|
||||||
|
{
|
||||||
|
$output = '';
|
||||||
|
|
||||||
|
if (($minutes = floor($duration / 60)) > 0) {
|
||||||
|
$output .= $minutes . 'min' . (($minutes > 1) ? 's' : '');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($seconds = number_format(fmod($duration, 60), 2)) > 0) {
|
||||||
|
if ($minutes > 0) {
|
||||||
|
$output .= ' ';
|
||||||
|
}
|
||||||
|
$output .= $seconds . 's';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function formatSecDifference($duration)
|
||||||
|
{
|
||||||
|
return number_format($duration, 2) . 's';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function outputTimeTaken()
|
||||||
|
{
|
||||||
|
$output = $this->formatMinDifference(microtime(true) - $this->startPoint);
|
||||||
|
|
||||||
|
$this->logger->info('Finished all tests! Time taken: {output}.', ['{output}' => $output]);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function sampleFile(array $replacements, $path)
|
||||||
|
{
|
||||||
|
return $this->sampleManager->write($path, $replacements);
|
||||||
|
}
|
||||||
|
}
|
16
server/vendor/php-opencloud/common/tests/integration/TestInterface.php
vendored
Normal file
16
server/vendor/php-opencloud/common/tests/integration/TestInterface.php
vendored
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\integration;
|
||||||
|
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
|
interface TestInterface
|
||||||
|
{
|
||||||
|
public function __construct(LoggerInterface $logger, SampleManagerInterface $sampleManager);
|
||||||
|
|
||||||
|
public function runTests();
|
||||||
|
|
||||||
|
public function runOneTest($name);
|
||||||
|
|
||||||
|
public function teardown();
|
||||||
|
}
|
59
server/vendor/php-opencloud/common/tests/integration/Utils.php
vendored
Normal file
59
server/vendor/php-opencloud/common/tests/integration/Utils.php
vendored
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OpenCloud\integration;
|
||||||
|
|
||||||
|
use GuzzleHttp\Client;
|
||||||
|
use OpenCloud\Identity\v2\Api;
|
||||||
|
use OpenCloud\Identity\v2\Service;
|
||||||
|
use OpenCloud\Common\Transport\HandlerStack;
|
||||||
|
use OpenCloud\Common\Transport\Utils as CommonUtils;
|
||||||
|
|
||||||
|
class Utils
|
||||||
|
{
|
||||||
|
public static function getAuthOptsV3()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'authUrl' => getenv('OS_AUTH_URL'),
|
||||||
|
'region' => getenv('OS_REGION_NAME'),
|
||||||
|
'user' => [
|
||||||
|
'id' => getenv('OS_USER_ID'),
|
||||||
|
'password' => getenv('OS_PASSWORD'),
|
||||||
|
],
|
||||||
|
'scope' => [
|
||||||
|
'project' => [
|
||||||
|
'id' => getenv('OS_PROJECT_ID'),
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getAuthOptsV2()
|
||||||
|
{
|
||||||
|
$httpClient = new Client([
|
||||||
|
'base_uri' => CommonUtils::normalizeUrl(getenv('OS_AUTH_URL')),
|
||||||
|
'handler' => HandlerStack::create(),
|
||||||
|
]);
|
||||||
|
return [
|
||||||
|
'authUrl' => getenv('OS_AUTH_URL'),
|
||||||
|
'region' => getenv('OS_REGION_NAME'),
|
||||||
|
'username' => getenv('OS_USERNAME'),
|
||||||
|
'password' => getenv('OS_PASSWORD'),
|
||||||
|
'tenantName' => getenv('OS_TENANT_NAME'),
|
||||||
|
'identityService' => new Service($httpClient, new Api),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getAuthOpts(array $options = [])
|
||||||
|
{
|
||||||
|
$authOptions = getenv('OS_IDENTITY_API_VERSION') == '2.0'
|
||||||
|
? self::getAuthOptsV2()
|
||||||
|
: self::getAuthOptsV3();
|
||||||
|
|
||||||
|
return array_merge($authOptions, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function toCamelCase($word, $separator = '_')
|
||||||
|
{
|
||||||
|
return str_replace($separator, '', ucwords($word, $separator));
|
||||||
|
}
|
||||||
|
}
|
10
server/vendor/php-opencloud/common/tests/integration/run.php
vendored
Normal file
10
server/vendor/php-opencloud/common/tests/integration/run.php
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$rootDir = dirname(dirname(__DIR__));
|
||||||
|
|
||||||
|
require_once $rootDir . '/vendor/autoload.php';
|
||||||
|
|
||||||
|
$basePath = $rootDir . '/samples';
|
||||||
|
|
||||||
|
$runner = new \OpenCloud\Integration\Runner($basePath);
|
||||||
|
$runner->runServices();
|
3
server/vendor/php-opencloud/common/tests/integration/script/compute_v2
vendored
Executable file
3
server/vendor/php-opencloud/common/tests/integration/script/compute_v2
vendored
Executable file
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
php tests/integration/Runner.php -s compute -v v2
|
3
server/vendor/php-opencloud/common/tests/integration/script/identity_v3
vendored
Executable file
3
server/vendor/php-opencloud/common/tests/integration/script/identity_v3
vendored
Executable file
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
php tests/integration/Runner.php -s identity -v v3
|
3
server/vendor/php-opencloud/common/tests/integration/script/networking_v2
vendored
Executable file
3
server/vendor/php-opencloud/common/tests/integration/script/networking_v2
vendored
Executable file
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
php tests/integration/Runner.php -s networking -v v2
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue