summaryrefslogtreecommitdiffstats
path: root/testapi/opnfv_testapi
diff options
context:
space:
mode:
Diffstat (limited to 'testapi/opnfv_testapi')
-rw-r--r--testapi/opnfv_testapi/common/check.py6
-rw-r--r--testapi/opnfv_testapi/handlers/pod_handlers.py23
-rw-r--r--testapi/opnfv_testapi/ui/components/pods/modals/createModal.html35
-rw-r--r--testapi/opnfv_testapi/ui/components/pods/pods.html145
-rw-r--r--testapi/opnfv_testapi/ui/components/pods/podsController.js195
-rw-r--r--testapi/opnfv_testapi/ui/index.html3
-rw-r--r--testapi/opnfv_testapi/ui/shared/alerts/confirmModalFactory.js9
7 files changed, 295 insertions, 121 deletions
diff --git a/testapi/opnfv_testapi/common/check.py b/testapi/opnfv_testapi/common/check.py
index 1155d24..db28e44 100644
--- a/testapi/opnfv_testapi/common/check.py
+++ b/testapi/opnfv_testapi/common/check.py
@@ -28,7 +28,7 @@ def is_authorized(method):
user_info = yield dbapi.db_find_one('users', {'user': testapi_id})
if not user_info:
raises.Unauthorized(message.not_lfid())
- if "owner" in kwargs:
+ if method.__name__ == "_create":
kwargs['owner'] = testapi_id
if self.table in ['projects']:
query = kwargs.get('query')
@@ -137,9 +137,9 @@ def new_not_exists(xstep):
query_data = query()
if self.table == 'pods':
if query_data.get('name') is not None:
- query_data['name'] = re.compile(query_data.get('name'),
- re.IGNORECASE)
+ query_data['name'] = re.compile('\\b' + query_data.get('name') + '\\b', re.IGNORECASE)
to_data = yield dbapi.db_find_one(self.table, query_data)
+ print to_data
if to_data:
raises.Forbidden(message.exist(self.table, query()))
ret = yield gen.coroutine(xstep)(self, *args, **kwargs)
diff --git a/testapi/opnfv_testapi/handlers/pod_handlers.py b/testapi/opnfv_testapi/handlers/pod_handlers.py
index abf5bf9..9e52ca0 100644
--- a/testapi/opnfv_testapi/handlers/pod_handlers.py
+++ b/testapi/opnfv_testapi/handlers/pod_handlers.py
@@ -57,22 +57,11 @@ class PodGURHandler(GenericPodHandler):
"""
self._get_one(query={'name': pod_name})
+ @swagger.operation(nickname='deletePodByName')
def delete(self, pod_name):
- """ Remove a POD
-
- # check for an existing pod to be deleted
- mongo_dict = yield self.db.pods.find_one(
- {'name': pod_name})
- pod = TestProject.pod(mongo_dict)
- if pod is None:
- raise HTTPError(HTTP_NOT_FOUND,
- "{} could not be found as a pod to be deleted"
- .format(pod_name))
-
- # just delete it, or maybe save it elsewhere in a future
- res = yield self.db.projects.remove(
- {'name': pod_name})
-
- self.finish_request(answer)
"""
- pass
+ @description: delete a pod by pod_name
+ @return 200: delete success
+ @raise 404: pods not exist
+ """
+ self._delete(query={'name': pod_name})
diff --git a/testapi/opnfv_testapi/ui/components/pods/modals/createModal.html b/testapi/opnfv_testapi/ui/components/pods/modals/createModal.html
new file mode 100644
index 0000000..9fe3c40
--- /dev/null
+++ b/testapi/opnfv_testapi/ui/components/pods/modals/createModal.html
@@ -0,0 +1,35 @@
+<div class="ball" style="padding:5px;">
+ <div class="modal-body">
+ <div class="form-horizontal">
+ <fieldset>
+ <div class="form-group">
+ <legend>Create Pod</legend>
+ <div class="row">
+ <div ng-repeat="require in PodModalCtrl.createRequirements" style="margin-left:15px">
+ <div class="update-project">
+ <label for="cpid" class="control-label col-sm-2">{{require.label|capitalize}}: </label>
+ <div class="col-sm-9">
+ <a ng-if="require.type == 'select'">
+ <select class="form-control" dynamic-model="'PodModalCtrl.pod.' + require.label" ng-options="option for option in require.selects"></select>
+ </a>
+ <a ng-if="require.type == 'text'">
+ <input type="text" class="form-control" dynamic-model="'PodModalCtrl.pod.' + require.label"/>
+ </a>
+ <a ng-if="require.type == 'textarea'">
+ <textarea rows="2" class="form-control" cols="50" dynamic-model="'PodModalCtrl.pod.' + require.label">
+ </textarea>
+ </a>
+ <p class="help-block"></p>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </fieldset>
+ </div>
+ </div>
+ <div class="modal-footer">
+ <button class="btn btn-primary" ng-click="PodModalCtrl.confirm()">Ok</button>
+ <button class="btn btn-default" ng-click="PodModalCtrl.cancel()">Cancel</button>
+ </div>
+</div> \ No newline at end of file
diff --git a/testapi/opnfv_testapi/ui/components/pods/pods.html b/testapi/opnfv_testapi/ui/components/pods/pods.html
index 72a9f6c..ca0458b 100644
--- a/testapi/opnfv_testapi/ui/components/pods/pods.html
+++ b/testapi/opnfv_testapi/ui/components/pods/pods.html
@@ -3,83 +3,88 @@
Querying pods is open to everybody.<br>
But only login users are granted the privilege to create the new pod.
</p>
-
<div class="row" style="margin-bottom:24px;"></div>
-
-<div class="pod-create" ng-class="{ 'hidden': ! auth.isAuthenticated }">
- <h4>Create</h4>
- <div class="row">
- <div ng-repeat="require in ctrl.createRequirements">
- <div class="create-pod" style="margin-left:24px;">
- <p class="input-group">
- <label for="cpid">{{require.label|capitalize}}: </label>
- <a ng-if="require.type == 'select'">
- <select dynamic-model="'ctrl.' + require.label" ng-options="option for option in require.selects"></select>
- </a>
- <a ng-if="require.type == 'text'">
- <input type="text" dynamic-model="'ctrl.' + require.label"/>
- </a>
- <a ng-if="require.type == 'textarea'">
- <textarea rows="2" cols="50" dynamic-model="'ctrl.' + require.label">
- </textarea>
- </a>
- </p>
- </div>
+<div cg-busy="{promise:ctrl.authRequest,message:'Loading'}"></div>
+<div cg-busy="{promise:ctrl.podsRequest,message:'Loading'}"></div>
+<br>
+<div class="row podTable" style="vertical-align:middle">
+ <div class="col-sm-1 pull-right" ng-class="{ 'hidden': !auth.isAuthenticated }" >
+ <button type="button" class="btn btn-danger" ng-click="ctrl.openBatchDeleteModal()">
+ <i class="fa fa-minus"></i> Delete</button>
</div>
-
- <div class="col-md-1" style="margin-top:12px;">
- <button type="submit" class="btn btn-primary" ng-click="ctrl.create()">Create</button>
+ <div class="col-sm-1 pull-right" ng-class="{ 'hidden': !auth.isAuthenticated }">
+ <button type="button" class="btn btn-success" ng-click="ctrl.openCreateModal()">
+ <i class="fa fa-plus"></i> Create</button>
</div>
- <div ng-show="ctrl.showError" class="col-md-11 alert alert-danger" role="alert">
- <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
- <span class="sr-only">Error:</span>
- {{ctrl.error}}
+ <div class="col-sm-1 pull-right">
+ <button type="button" class="btn btn-success" ng-click="ctrl.listPods()">
+ <i class="fa fa-search"></i> Filter</button>
</div>
- <div ng-show="ctrl.showSuccess" class="col-md-11 alert alert-success" role="alert">
- <span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
- Create Success
+ <div class="col-sm-3 pull-right">
+ <span style="margin-top:6px">Search:&nbsp;&nbsp;</span>
+ <input type="text" class="form-control search" ngModel="filter" placeholder="Search String">
+ </div>
+ <div class="col-md-3 row pull-right">
+ <span style="margin-top:6px">Filter:&nbsp;&nbsp;</span>
+ <select ng-model="ctrl.filter" class="form-control">
+ <option value="name">Name</option>
+ <option value="owner">Owner</option>
+ </select>
</div>
- </div>
</div>
-
-<div class="pods-filters" style="margin-top:36px;">
- <h4>Filters</h4>
- <div class="row">
- <div class="col-md-3" style="margin-top:12px; margin-left:8px;">
- <button type="submit" class="btn btn-primary" ng-click="ctrl.update()">Filter</button>
- <button type="submit" class="btn btn-primary btn-danger" ng-click="ctrl.clearFilters()">Clear</button>
- </div>
+<div class="col-md-12">
+ <div ng-show="ctrl.showError" class="col-md-12 alert alert-danger" role="alert">
+ <span class="pull-right">&nbsp;{{ctrl.error}}</span>
+ <span class="glyphicon glyphicon-exclamation-sign pull-right" aria-hidden="true" >Error:</span>
+ </div>
+ <div ng-show="ctrl.showSuccess" class="col-md-12 alert alert-success" role="alert">
+ <span class="pull-right">&nbsp;{{ctrl.success}}</span>
+ <span class="glyphicon glyphicon-ok pull-right" aria-hidden="true"></span>
</div>
</div>
-
-<div cg-busy="{promise:ctrl.authRequest,message:'Loading'}"></div>
-<div cg-busy="{promise:ctrl.podsRequest,message:'Loading'}"></div>
-
-<div ng-show="ctrl.data" class="pods-table" style="margin-top:24px; margin-left:8px;">
- <table ng-data="ctrl.data.pods" ng-show="ctrl.data" class="table table-striped table-hover">
+<div class="col-md-12" style="padding-right:0px">
+ <div class="table-responsive">
+ <table class="table table-bordered table-hover" ng-data="ctrl.data.pods">
+ <thead>
+ <tr style="
+ text-align: center;">
+ <th>Bulk Select</th>
+ <th>Name</th>
+ <th>Details</th>
+ <th>Role</th>
+ <th>Mode</th>
+ <th>CreatedAt</th>
+ <th>Operation</th>
+ </tr>
+ </thead>
<tbody>
- <tr ng-repeat-start="(index, pod) in ctrl.data.pods">
- <td>
- <a href="#" ng-click="showPod = !showPod">{{pod.name}}</a>
- <div class="show-pod" ng-class="{ 'hidden': ! showPod }" style="margin-left:24px;">
- <p>
- owner: {{pod.owner}}<br>
- role: {{pod.role}}<br>
- mode: {{pod.mode}}<br>
- create_date: {{pod.creation_date}}<br>
- details: {{pod.details}}
- </p>
- </div>
- </td>
- </tr>
- <tr ng-repeat-end=>
- </tr>
+ <tr ng-repeat-start="(index, pod) in ctrl.data.pods" style="padding:9px">
+ <td>
+ <div class="text-center">
+ <input type="checkbox" value="{{pod.name}}" ng-model="ctrl.checkBox[index]" >
+ </div>
+ </td>
+ <td>{{pod.name}}</td>
+ <td style="width:20%;">{{pod.details}}</td>
+ <td>{{pod.role}}</td>
+ <td>{{pod.mode}}</td>
+ <td>
+ {{pod.creation_date}}
+ </td>
+ <td>
+ <span class="podTable-col">
+ <a class="text-warning" title="Edit" ng-class="{ 'hidden': !auth.isAuthenticated }" >
+ <i class="fa fa-pencil-square-o"></i></a>
+ <a class="text-danger" ng-click="ctrl.openDeleteModal(pod.name)" title="Delete" ng-class="{ 'hidden': !auth.isAuthenticated }">
+ <i class="fa fa-trash-o"></i></a>
+ <a class="text-info" ><i class="fa fa-eye"></i></a>
+ </span>
+ </td>
+ </tr>
+ <tr ng-repeat-end=>
+ </tr>
</tbody>
- </table>
-</div>
-<br>
-<div ng-show="ctrl.showError" class="alert alert-danger" ng-class="{ 'hidden': auth.isAuthenticated }" role="alert">
- <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
- <span class="sr-only">Error:</span>
- {{ctrl.error}}
-</div>
+ </table>
+ </div>
+ </div>
+</div> \ No newline at end of file
diff --git a/testapi/opnfv_testapi/ui/components/pods/podsController.js b/testapi/opnfv_testapi/ui/components/pods/podsController.js
index 9789cf2..fa60143 100644
--- a/testapi/opnfv_testapi/ui/components/pods/podsController.js
+++ b/testapi/opnfv_testapi/ui/components/pods/podsController.js
@@ -20,7 +20,8 @@
.controller('PodsController', PodsController);
PodsController.$inject = [
- '$scope', '$http', '$filter', '$state', 'testapiApiUrl','raiseAlert'
+ '$scope', '$http', '$filter', '$state', '$window', '$uibModal', 'testapiApiUrl','raiseAlert',
+ 'confirmModal'
];
/**
@@ -28,29 +29,23 @@
* This controller is for the '/pods' page where a user can browse
* through pods declared in TestAPI.
*/
- function PodsController($scope, $http, $filter, $state, testapiApiUrl,
- raiseAlert) {
+ function PodsController($scope, $http, $filter, $state, $window, $uibModal, testapiApiUrl,
+ raiseAlert, confirmModal) {
var ctrl = this;
ctrl.url = testapiApiUrl + '/pods';
+ ctrl.checkBox = []
+ ctrl.checkBoxList = [];
ctrl.create = create;
- ctrl.update = update;
+ ctrl.listPods = listPods;
ctrl.open = open;
+ ctrl.filter = 'name'
ctrl.clearFilters = clearFilters;
-
- ctrl.roles = ['community-ci', 'production-ci'];
- ctrl.modes = ['metal', 'virtual'];
- ctrl.createRequirements = [
- {label: 'name', type: 'text', required: true},
- {label: 'mode', type: 'select', selects: ctrl.modes},
- {label: 'role', type: 'select', selects: ctrl.roles},
- {label: 'details', type: 'textarea', required: false}
- ];
-
- ctrl.name = '';
- ctrl.role = 'community-ci';
- ctrl.mode = 'metal';
- ctrl.details = '';
+ ctrl.openDeleteModal = openDeleteModal
+ ctrl.openBatchDeleteModal = openBatchDeleteModal
+ ctrl.openCreateModal = openCreateModal
+ ctrl.podDelete = podDelete
+ ctrl.batchDelete = batchDelete;
/**
* This is called when the date filter calendar is opened. It
@@ -70,27 +65,29 @@
* listing.
*/
function clearFilters() {
- ctrl.update();
+ ctrl.listPods();
}
/**
* This will contact the TestAPI to create a new pod.
*/
- function create() {
+ function create(pod) {
ctrl.showError = false;
ctrl.showSuccess = false;
-
- if(ctrl.name != ""){
+ console.log(pod);
+ if(pod.name != ""){
var pods_url = ctrl.url;
var body = {
- name: ctrl.name,
- mode: ctrl.mode,
- role: ctrl.role,
- details: ctrl.details
+ name: pod.name,
+ mode: pod.mode,
+ role: pod.role,
+ details: pod.details
};
ctrl.podsRequest =
$http.post(pods_url, body).success(function (data) {
ctrl.showSuccess = true ;
+ ctrl.success = "Create Success"
+ ctrl.listPods();
}).catch(function (data) {
ctrl.showError = true;
ctrl.error = "Error creating the new pod from server: " + data.statusText;
@@ -105,11 +102,12 @@
/**
* This will contact the TestAPI to get a listing of declared pods.
*/
- function update() {
+ function listPods() {
ctrl.showError = false;
ctrl.podsRequest =
$http.get(ctrl.url).success(function (data) {
ctrl.data = data;
+ // mapNametoRandom
}).error(function (error) {
ctrl.data = null;
ctrl.showError = true;
@@ -118,5 +116,148 @@
angular.toJson(error);
});
}
+
+ /**
+ * This will contact the TestAPI to delete a pod for given
+ * name.
+ */
+ function podDelete(podName){
+ var pods_url = ctrl.url + "/" + podName
+ $http.delete(pods_url).success(function(){
+ ctrl.showSuccess = true ;
+ ctrl.success = "Delete Success"
+ ctrl.listPods();
+ }).catch(function (data) {
+ ctrl.showError = true;
+ ctrl.error = data.statusText;
+ });
+ }
+
+ /**
+ * This will delete list of pods.
+ */
+ function batchDelete(){
+ var index;
+ var checkedBox = [];
+ console.log(ctrl.checkBox)
+ for(index in ctrl.checkBox){
+ if(!ctrl.showError){
+ if(ctrl.checkBox[index]){
+ podDelete(ctrl.data.pods[index].name);
+ }
+ }
+ }
+ ctrl.checkBox = []
+ }
+
+ /**
+ * This will open the modal that will show the batch delete confirm
+ * message
+ */
+ function openBatchDeleteModal() {
+ confirmModal("Delete",ctrl.batchDelete);
+ }
+
+ /**
+ * This will open the modal that will show the delete confirm
+ * message
+ */
+ function openDeleteModal(name) {
+ console.log(name)
+ confirmModal("Delete", ctrl.podDelete, name);
+ }
+
+ /**
+ * This will open the modal that will show the create
+ * view
+ */
+ function openCreateModal(){
+ $uibModal.open({
+ templateUrl: 'testapi-ui/components/pods/modals/createModal.html',
+ controller: 'PodModalCtrl as PodModalCtrl',
+ size: 'md',
+ resolve: {
+ data: function () {
+ return {
+ text: "Create",
+ successHandler: ctrl.create,
+ };
+ }
+ }
+ });
+ }
+
+ // function openUpdateModal(podName){
+ // $uibModal.open({
+ // templateUrl: 'testapi-ui/components/pods/modals/createModal.html',
+ // controller: 'PodModalCtrl as PodModalCtrl',
+ // size: 'md',
+ // resolve: {
+ // data: function () {
+ // return {
+ // text: "Update",
+ // successHandler: ctrl.update,
+ // // pod: ctrl.
+ // };
+ // }
+ // }
+ // });
+ // }
+ ctrl.listPods();
}
+
+
+ /**
+ * TestAPI Pod Modal Controller
+ * This controller is for the create modal where a user can create
+ * the project information and for the edit modal where user can
+ * edit the pods details
+ */
+ angular.module('testapiApp').controller('PodModalCtrl', PodModalCtrl);
+ PodModalCtrl.$inject = ['$scope', '$uibModalInstance', 'data'];
+ function PodModalCtrl($scope, $uibModalInstance, data) {
+ var ctrl = this;
+ ctrl.confirm = confirm;
+ ctrl.cancel = cancel;
+ ctrl.data = angular.copy(data);
+ ctrl.roles = ['community-ci', 'production-ci'];
+ ctrl.modes = ['metal', 'virtual'];
+ ctrl.createRequirements = [
+ {label: 'name', type: 'text', required: true},
+ {label: 'mode', type: 'select', selects: ctrl.modes},
+ {label: 'role', type: 'select', selects: ctrl.roles},
+ {label: 'details', type: 'textarea', required: false}
+ ];
+ ctrl.pod = {
+ name : '',
+ role : 'community-ci',
+ mode : 'metal',
+ details : ''
+ }
+
+ if(ctrl.data.pod){
+ ctrl.pod = ctrl.data.pod
+ }
+
+ /**
+ * Initiate confirmation and call the success handler with the
+ * inputs.
+ */
+ function confirm() {
+ $uibModalInstance.close();
+ if (angular.isDefined(ctrl.data.successHandler)) {
+ ctrl.data.successHandler(ctrl.pod);
+ }
+ }
+
+ /**
+ * Close the confirm modal without initiating changes.
+ */
+ function cancel() {
+ $uibModalInstance.dismiss('cancel');
+ }
+ }
+
+
})();
+
diff --git a/testapi/opnfv_testapi/ui/index.html b/testapi/opnfv_testapi/ui/index.html
index e15fff6..00c2b9c 100644
--- a/testapi/opnfv_testapi/ui/index.html
+++ b/testapi/opnfv_testapi/ui/index.html
@@ -27,7 +27,10 @@
<link rel="stylesheet" href="testapi-ui/assets/lib/bootstrap/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="testapi-ui/assets/lib/angular-busy/dist/angular-busy.min.css">
<link rel="stylesheet" href="testapi-ui/assets/css/style.css">
+ <link rel="stylesheet" href="testapi-ui/assets/lib/font-awesome-4.7.0/css/font-awesome.min.css">
+ <script src="testapi-ui/assets/lib/jquery/jquery-3.2.1.min.js"></script>
+ <script src="testapi-ui/assets/lib/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="testapi-ui/assets/lib/angular/angular.min.js"></script>
<script src="testapi-ui/assets/lib/angular-ui-router/release/angular-ui-router.min.js"></script>
<script src="testapi-ui/assets/lib/angular-resource/angular-resource.min.js"></script>
diff --git a/testapi/opnfv_testapi/ui/shared/alerts/confirmModalFactory.js b/testapi/opnfv_testapi/ui/shared/alerts/confirmModalFactory.js
index aba205e..fc0bfe6 100644
--- a/testapi/opnfv_testapi/ui/shared/alerts/confirmModalFactory.js
+++ b/testapi/opnfv_testapi/ui/shared/alerts/confirmModalFactory.js
@@ -11,7 +11,7 @@
* Opens confirm modal dialog with input textbox
*/
function confirmModal($uibModal) {
- return function(text, successHandler) {
+ return function(text, successHandler, name) {
$uibModal.open({
templateUrl: '/testapi-ui/shared/alerts/confirmModal.html',
controller: 'CustomConfirmModalController as confirmModal',
@@ -20,7 +20,8 @@
data: function () {
return {
text: text,
- successHandler: successHandler
+ successHandler: successHandler,
+ name: name
};
}
}
@@ -45,7 +46,7 @@
ctrl.cancel = cancel;
ctrl.data = angular.copy(data);
-
+ console.log(ctrl.data)
/**
* Initiate confirmation and call the success handler with the
* input text.
@@ -53,7 +54,7 @@
function confirm() {
$uibModalInstance.close();
if (angular.isDefined(ctrl.data.successHandler)) {
- ctrl.data.successHandler(ctrl.inputText);
+ ctrl.data.successHandler(ctrl.data.name);
}
}