1
0
Fork 0
mirror of https://github.com/mmumshad/ansible-playable.git synced 2025-03-09 23:38:54 +00:00

Initial Commit

This commit is contained in:
Mumshad Mannambeth 2017-06-07 13:36:44 -04:00
commit c92f737237
273 changed files with 16964 additions and 0 deletions

View file

@ -0,0 +1,278 @@
'use strict';
const angular = require('angular');
const uiRouter = require('angular-ui-router');
import routes from './inventory.routes';
export class InventoryComponent {
/*@ngInject*/
constructor($scope, $uibModal, ansible) {
'ngInject';
$scope.selectedInventory = {inventory: "", content: ""};
$scope.editInventory = {value: false};
$scope.selectedGroup = {group: null};
$scope.selectedHost = {host: null};
$scope.complexVar = {};
$scope.$on('projectLoaded', function () {
$scope.getInventorys()
});
//To fix a warning message in console
$scope.aceLoaded = function(_editor){
_editor.$blockScrolling = Infinity;
};
// --------------------------------------- PLAYBOOKS ----------------
$scope.getInventorys = function () {
ansible.getInventoryList(
function (response) {
$scope.inventorys = response.data;
},
function (response) {
console.log(response.data)
}
)
};
if ($scope.$parent.selectedProject && $scope.$parent.selectedProject.ansibleEngine) {
$scope.getInventorys()
}
$scope.loadingModuleCode = false;
$scope.showInventoryCode = function (inventory_name) {
$scope.loadingModuleCode = true;
if (!inventory_name) {
$scope.selectedInventory.content = "Select a module";
return;
}
ansible.readInventory(inventory_name, function (response) {
$scope.loadingModuleCode = false;
$scope.selectedInventory.content = response.data.split("Stream :: close")[0];
$scope.inventory_data_json = ansible.parseINIString($scope.selectedInventory.content);
$scope.inventory_data_json['name'] = inventory_name
});
};
$scope.$watch('selectedInventory.inventory', function (newValue, oldValue) {
if (newValue && newValue !== oldValue) {
$scope.selectedInventory.content = "Loading Code...";
$scope.showInventoryCode(newValue)
}
});
$scope.showCreatInventoryModal = function () {
var modalInstance = $uibModal.open({
animation: true,
/*templateUrl: 'createTaskContent.html',*/
templateUrl: 'app/designer/inventory/new_inventory/new_inventory.html',
controller: 'NewInventoryController',
size: 'md',
backdrop: 'static',
keyboard: false,
closeByEscape: false,
closeByDocument: false,
resolve: {
selectedProject: function () {
return $scope.$parent.selectedProject
}
}
});
modalInstance.result.then(function () {
$scope.getInventorys();
}, function () {
});
};
$scope.editGroup = function (group) {
$scope.showCreateGroupModal(group);
};
$scope.showCreateGroupModal = function (editGroup) {
var modalInstance = $uibModal.open({
animation: true,
/*templateUrl: 'createTaskContent.html',*/
templateUrl: 'app/designer/inventory/new_group/new_group.html',
controller: 'NewGroupController',
size: 'lg',
backdrop: 'static',
keyboard: false,
closeByEscape: false,
closeByDocument: false,
resolve: {
selectedProject: function () {
return $scope.$parent.selectedProject
},
editGroup: function () {
return editGroup
}
}
});
modalInstance.result.then(function (group) {
if(!editGroup)$scope.addGroup(group);
else $scope.selectedInventory.content = ansible.jsonToAnsibleInventoryIni($scope.inventory_data_json);
$scope.saveInventory();
}, function () {
});
};
$scope.editHost = function (host) {
var hostMemberOfGroups = getHostMemberOfGroups(host);
$scope.showCreateHostModal({name: host, members: hostMemberOfGroups.join(',')});
};
$scope.showCreateHostModal = function (editHost) {
var modalInstance = $uibModal.open({
animation: true,
/*templateUrl: 'createTaskContent.html',*/
templateUrl: 'app/designer/inventory/new_host/new_host.html',
controller: 'NewHostController',
size: 'lg',
backdrop: 'static',
keyboard: false,
closeByEscape: false,
closeByDocument: false,
resolve: {
selectedProject: function () {
return $scope.$parent.selectedProject
},
editHost: function () {
return editHost
}
}
});
modalInstance.result.then(function (host) {
$scope.addHost(host);
$scope.saveInventory();
}, function () {
});
};
$scope.saveInventory = function () {
$scope.saveInventoryLoading = true;
ansible.createInventory($scope.selectedInventory.inventory, $scope.selectedInventory.content,
function (response) {
$scope.saveInventoryLoading = false;
$scope.editInventory.value = false;
},
function (response) {
$scope.saveInventoryLoading = false;
$scope.err_msg = response.data;
})
};
$scope.deleteInventory = function () {
$scope.deleteInventoryLoading = true;
ansible.deleteInventory($scope.selectedInventory.inventory,
function (response) {
$scope.deleteInventoryLoading = false;
$scope.selectedInventory.inventory = "";
$scope.getInventorys();
},
function (response) {
$scope.deleteInventoryLoading = false;
$scope.err_msg = response.data;
})
};
$scope.addGroup = function (group) {
$scope.inventory_data_json.groups.push(group);
$scope.selectedInventory.content = ansible.jsonToAnsibleInventoryIni($scope.inventory_data_json);
// To refresh All Hosts list
$scope.inventory_data_json = ansible.parseINIString($scope.selectedInventory.content)
};
$scope.addHost = function (host) {
if ($scope.inventory_data_json.hosts.indexOf(host.name) < 0)
$scope.inventory_data_json.hosts.push(host.name);
var host_member_of_groups = host.members.split(',');
angular.forEach($scope.inventory_data_json.groups, function (group) {
if ((host_member_of_groups.indexOf(group.name)) > -1 && group.members.indexOf(host.name) < 0) {
group.members.push(host.name)
}
});
$scope.selectedInventory.content = ansible.jsonToAnsibleInventoryIni($scope.inventory_data_json);
// To refresh All Hosts list
$scope.inventory_data_json = ansible.parseINIString($scope.selectedInventory.content)
};
$scope.deleteGroup = function (index) {
$scope.inventory_data_json.groups.splice(index, 1);
$scope.selectedInventory.content = ansible.jsonToAnsibleInventoryIni($scope.inventory_data_json);
// To refresh All Hosts list
$scope.inventory_data_json = ansible.parseINIString($scope.selectedInventory.content);
$scope.saveInventory();
};
$scope.deleteHost = function (index, group) {
var hostname = $scope.inventory_data_json.hosts[index];
$scope.inventory_data_json.hosts.splice(index, 1);
angular.forEach($scope.inventory_data_json.groups, function (group) {
var memberIndex = group.members.indexOf(hostname)
if (memberIndex > -1) {
group.members.splice(memberIndex, 1)
}
});
$scope.selectedInventory.content = ansible.jsonToAnsibleInventoryIni($scope.inventory_data_json);
// To refresh All Hosts list
$scope.inventory_data_json = ansible.parseINIString($scope.selectedInventory.content);
$scope.saveInventory();
};
var getHostMemberOfGroups = function (host) {
var groups = [];
angular.forEach($scope.inventory_data_json.groups, function (group) {
var memberIndex = group.members.indexOf(host);
if (memberIndex > -1) {
groups.push(group.name)
}
});
return groups;
};
}
}
export default angular.module('webAppApp.inventory', [uiRouter])
.config(routes)
.component('inventory', {
template: require('./inventory.html'),
controller: InventoryComponent,
controllerAs: 'inventoryCtrl'
})
.name;

View file

@ -0,0 +1,17 @@
'use strict';
describe('Component: InventoryComponent', function() {
// load the controller's module
beforeEach(module('webAppApp.inventory'));
var InventoryComponent;
// Initialize the controller and a mock scope
beforeEach(inject(function($componentController) {
InventoryComponent = $componentController('inventory', {});
}));
it('should ...', function() {
expect(1).to.equal(1);
});
});

View file

@ -0,0 +1,154 @@
<div class="col-md-8">
<button class="btn btn-default" ng-click="showCreatInventoryModal()">Create Inventory <span class="fa fa-plus"></span></button>
<!--<button class="btn btn-default" ng-if="!editInventory.value" ng-click="editInventory.value = true">Edit <span ng-if="!saveInventoryLoading" class="fa fa-edit"></span></button>
<button class="btn btn-primary" ng-if="editInventory.value" ng-disabled="!selectedInventory.inventory" ng-click="saveInventory()">Save <span ng-if="!saveInventoryLoading" class="fa fa-save"></span><span ng-if="saveInventoryLoading" class="fa fa-spinner fa-spin"></span></button>-->
<button class="btn btn-danger" confirm="Are you sure you want to delete inventory? " ng-disabled="!selectedInventory.inventory" ng-click="deleteInventory()">Delete <span ng-if="!deleteInventoryLoading" class="fa fa-trash-o"></span><span ng-if="deleteInventoryLoading" class="fa fa-spinner fa-spin"></span></button>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Select</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="inventory in inventorys">
<td><input name="playGroup" type="radio" ng-model="selectedInventory.inventory" ng-value="inventory">
</td>
<td>{{inventory}}</td>
</tr>
</tbody>
</table>
</div>
<div class="row">
<div class="col-md-6">
<div class="panel">
<div class="panel panel-default">
<div class="panel-heading">Groups - {{inventory_data_json.groups.length}}</div>
<div class="panel-body">
<button class="btn btn-default" ng-disabled="!selectedInventory.inventory" ng-click="showCreateGroupModal()">Create Group <span class="fa fa-plus"></span></button>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Select</th>
<th>Name</th>
<th>Members</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="group in inventory_data_json.groups">
<td><input name="groupsRadioGroup" type="radio" ng-model="selectedGroup.group" ng-value="group">
</td>
<td>{{group.name}}</td>
<td>{{group.members.length}}</td>
<td>
<div class="btn-group">
<label ng-show="group.type == 'userdefined'" class="btn btn-default btn-xs" ng-click="editGroup(group)" ><span class="fa fa-edit"></span></label>
<label ng-show="group.type == 'userdefined'" class="btn btn-danger btn-xs" confirm="Are you sure you want to delete this group?" ng-click="deleteGroup($index)" ><span class="fa fa-trash-o"></span></label>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="panel" ng-show="selectedGroup.group.members">
<div class="panel panel-default">
<div class="panel-heading">Group Members - {{selectedGroup.group.name}}</div>
<div class="panel-body">
<div class="table-responsive" >
<table class="table">
<thead>
<tr>
<th>Select</th>
<th>Name</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="host in selectedGroup.group.members">
<td><input name="hostsRadioGroup" type="radio" ng-model="selectedHost.host" ng-value="host">
</td>
<td>{{host}}</td>
<td>
<div class="btn-group">
<label class="btn btn-danger btn-xs" confirm="Are you sure you want to delete host and remove it from all groups?" ng-click="deleteHost($index)" ><span class="fa fa-trash-o"></span></label>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="panel">
<div class="panel panel-default">
<div class="panel-heading">Hosts - {{inventory_data_json.hosts.length}}</div>
<div class="panel-body">
<button class="btn btn-default" ng-disabled="!selectedInventory.inventory" ng-click="showCreateHostModal()">Create Host <span class="fa fa-plus"></span></button>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Select</th>
<th>Name</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="host in inventory_data_json.hosts">
<td><input name="hostsRadioGroup" type="radio" ng-model="selectedHost.host" ng-value="host">
</td>
<td>{{host}}</td>
<td>
<div class="btn-group">
<label class="btn btn-default btn-xs" ng-click="editHost(host)" ><span class="fa fa-edit"></span></label>
<label class="btn btn-danger btn-xs" confirm="Are you sure you want to delete host and remove it from all groups?" ng-click="deleteHost($index)" ><span class="fa fa-trash-o"></span></label>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
</div>
</div>
</div>
<div class="col-md-4">
<div ng-readonly="!editInventory.value" ui-ace="{theme:'twilight',document:'INI',mode:'ini',onChange:codeChanged,onLoad:aceLoaded}" ng-model="selectedInventory.content">
</div>
</div>

View file

@ -0,0 +1,10 @@
'use strict';
export default function($stateProvider) {
'ngInject';
$stateProvider
.state('designer.inventory', {
url: '/inventory',
template: '<inventory></inventory>'
});
}

View file

@ -0,0 +1,82 @@
'use strict';
const angular = require('angular');
/*@ngInject*/
export function newGroupController($scope,$uibModalInstance, yamlFile, ansible, selectedProject, editGroup, YAML, $timeout) {
'ngInject';
$scope.newGroup = editGroup || {name:null};
$scope.variableViewType = {type:'YAML'};
$scope.complexVar = {};
$scope.complexVarString = {};
console.log("$scope.newGroup.name" + $scope.newGroup.name);
$scope.aceLoaded = function (_editor) {
_editor.$blockScrolling = Infinity;
};
if($scope.newGroup.members){
$scope.newGroup.members = $scope.newGroup.members.join(',');
}
if($scope.newGroup.name){
$scope.getGroupLoading = true;
ansible.getGroupVarsFile($scope.newGroup.name,
function(response){
$scope.getGroupLoading = false;
$scope.complexVarStringYaml = response.data;
$scope.complexVar = YAML.parse(response.data);
$timeout(function(){
$scope.$broadcast('membersUpdated')
},100);
},function(response){
$scope.getGroupLoading = false;
$scope.err_msg = response.data;
})
}
$scope.$watch('complexVar',function(){
$scope.complexVarString = JSON.stringify($scope.complexVar, null, '\t');
$scope.complexVarStringYaml = yamlFile.jsonToYamlFile($scope.complexVar, 'Group Variables - ' + $scope.newGroup.name);
}, true);
$scope.$watch('newGroup',function(){
$scope.complexVarString = JSON.stringify($scope.complexVar, null, '\t');
$scope.complexVarStringYaml = yamlFile.jsonToYamlFile($scope.complexVar, 'Group Variables - ' + $scope.newGroup.name);
}, true);
$scope.createGroup = function(){
$scope.createGroupLoading = true;
ansible.updateGroupVarsFile($scope.newGroup.name,$scope.complexVarStringYaml,
function(response){
$scope.createGroupLoading = false;
console.log("Success");
$scope.ok()
},function(response){
$scope.createGroupLoading = false;
$scope.err_msg = response.data;
});
};
$scope.ok = function () {
var resultGroup = {name:$scope.newGroup.name};
if($scope.newGroup.members){
resultGroup.members = $scope.newGroup.members.split(',');
$scope.newGroup.members = $scope.newGroup.members.split(',')
}
$uibModalInstance.close(resultGroup);
};
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
}
export default angular.module('webAppApp.new_group', [])
.controller('NewGroupController', newGroupController)
.name;

View file

@ -0,0 +1,17 @@
'use strict';
describe('Controller: NewGroupCtrl', function() {
// load the controller's module
beforeEach(module('webAppApp.new_group'));
var NewGroupCtrl;
// Initialize the controller and a mock scope
beforeEach(inject(function($controller) {
NewGroupCtrl = $controller('NewGroupCtrl', {});
}));
it('should ...', function() {
expect(1).to.equal(1);
});
});

View file

@ -0,0 +1,45 @@
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">New Group</h4>
</div>
<div class="modal-body">
<p class="form-group">
<label>Group Name</label>
<input type="text" ng-model="newGroup.name" class="form-control">
</p>
<p class="form-group">
<label>Group Members</label>
<input type="text" ng-model="newGroup.members" class="form-control" placeholder="Hosts list separated by coma">
</p>
<label> Group Variables </label>
<div class="row">
<div class="col-md-6">
<complex-var members="complexVar" path="'Parent'" type="'object'" input-width="'400px'">
</complex-var>
</div>
<div class="col-md-6">
<input name="typeRadioGroup" type="radio" ng-model="variableViewType.type" ng-value="'JSON'"> JSON
<input name="typeRadioGroup" type="radio" ng-model="variableViewType.type" ng-value="'YAML'"> YAML
<div ng-readonly="true" ui-ace="{th1eme:'twilight',document:'yaml',mode:'yaml',onChange:codeChanged,onLoad:aceLoaded}" ng-show="variableViewType.type == 'YAML'" ng-model="complexVarStringYaml" style="max-height: 200px;">
</div>
<div ng-readonly="true" ui-ace="{th1eme:'twilight',document:'json',mode:'json',onChange:codeChanged,onLoad:aceLoaded}" ng-show="variableViewType.type == 'JSON'" ng-model="complexVarString" style="max-height: 200px;">
</div>
</div>
</div>
</div>
<div class="alert alert-danger" ng-if="err_msg">{{err_msg}}</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-disabled="!newGroup.name" ng-click="createGroup()">Create <span ng-if="createGroupLoading" class="fa fa-spinner fa-spin"></span></button>
<button class="btn btn-default" type="button" ng-click="cancel()">Close</button>
</div>
</div>

View file

@ -0,0 +1,69 @@
'use strict';
const angular = require('angular');
/*@ngInject*/
export function newHostController($scope,$uibModalInstance, yamlFile, ansible, selectedProject, editHost, YAML, $timeout) {
$scope.newHost = editHost || {name:null};
$scope.variableViewType = {type:'YAML'};
$scope.complexVar = {};
$scope.complexVarString = {};
if($scope.newHost.name){
$scope.getHostLoading = true;
ansible.getHostVarsFile($scope.newHost.name,
function(response){
$scope.getHostLoading = false;
$scope.complexVarStringYaml = response.data;
$scope.complexVar = YAML.parse(response.data);
$timeout(function(){
$scope.$broadcast('membersUpdated')
},100);
},function(response){
$scope.getHostLoading = false;
$scope.err_msg = response.data;
})
}
$scope.$watch('complexVar',function(){
$scope.complexVarString = JSON.stringify($scope.complexVar, null, '\t');
$scope.complexVarStringYaml = yamlFile.jsonToYamlFile($scope.complexVar, 'Host Variables - ' + $scope.newHost.name);
}, true);
$scope.$watch('newHost',function(){
$scope.complexVarString = JSON.stringify($scope.complexVar, null, '\t');
$scope.complexVarStringYaml = yamlFile.jsonToYamlFile($scope.complexVar, 'Host Variables - ' + $scope.newHost.name);
}, true);
$scope.aceLoaded = function(_editor){
_editor.$blockScrolling = Infinity;
};
$scope.createHost = function(){
$scope.createHostLoading = true;
ansible.updateHostVarsFile($scope.newHost.name,$scope.complexVarStringYaml,
function(response){
$scope.createHostLoading = false;
console.log("Success");
$scope.ok()
},function(response){
$scope.createHostLoading = false;
$scope.err_msg = response.data;
});
};
$scope.ok = function () {
if(!$scope.newHost.members)$scope.newHost.members = 'Un grouped';
$uibModalInstance.close($scope.newHost);
};
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
}
export default angular.module('webAppApp.new_host', [])
.controller('NewHostController', newHostController)
.name;

View file

@ -0,0 +1,17 @@
'use strict';
describe('Controller: NewHostCtrl', function() {
// load the controller's module
beforeEach(module('webAppApp.new_host'));
var NewHostCtrl;
// Initialize the controller and a mock scope
beforeEach(inject(function($controller) {
NewHostCtrl = $controller('NewHostCtrl', {});
}));
it('should ...', function() {
expect(1).to.equal(1);
});
});

View file

@ -0,0 +1,46 @@
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">New Host</h4>
</div>
<div class="modal-body">
<p class="form-group">
<label>Host Name</label>
<input type="text" ng-model="newHost.name" class="form-control">
</p>
<p class="form-group">
<label>Member of Groups</label>
<input type="text" ng-model="newHost.members" class="form-control" placeholder="Hosts list separated by coma">
</p>
<label> Host Variables </label>
<div class="row">
<div class="col-md-6">
<complex-var members="complexVar" path="'Parent'" type="'object'" input-width="'400px'">
</complex-var>
</div>
<div class="col-md-6">
<input name="typeRadioHost" type="radio" ng-model="variableViewType.type" ng-value="'JSON'"> JSON
<input name="typeRadioHost" type="radio" ng-model="variableViewType.type" ng-value="'YAML'"> YAML
<div ng-readonly="true" ui-ace="{th1eme:'twilight',document:'yaml',mode:'yaml',onChange:codeChanged}" ng-show="variableViewType.type == 'YAML'" ng-model="complexVarStringYaml" style="max-height: 200px;">
</div>
<div ng-readonly="true" ui-ace="{th1eme:'twilight',document:'json',mode:'json',onChange:codeChanged,onLoad:aceLoaded}" ng-show="variableViewType.type == 'JSON'" ng-model="complexVarString" style="max-height: 200px;">
</div>
</div>
</div>
</div>
<div class="alert alert-danger" ng-if="err_msg">{{err_msg}}</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-disabled="!newHost.name" ng-click="createHost()">Create <span ng-if="createHostLoading" class="fa fa-spinner fa-spin"></span></button>
<button class="btn btn-default" type="button" ng-click="cancel()">Close</button>
</div>
</div>

View file

@ -0,0 +1,40 @@
'use strict';
const angular = require('angular');
/*@ngInject*/
export function newInventoryController($scope,$uibModalInstance,ansible,selectedProject) {
$scope.newInventory = {name:null};
$scope.createInventoryLoading = false;
$scope.createInventory = function(){
if($scope.newInventory.name.match(/\./)){
$scope.err_msg = "Inventory files should not have extension"
return
}
$scope.createInventoryLoading = true;
ansible.createInventory($scope.newInventory.name,'# Inventory File - ' + $scope.newInventory.name,
function(response){
$scope.createInventoryLoading = false;
$scope.ok();
},
function(response){
$scope.createInventoryLoading = false;
$scope.err_msg = response.data;
})
};
$scope.ok = function () {
$uibModalInstance.close(null);
};
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
}
export default angular.module('webAppApp.new_inventory', [])
.controller('NewInventoryController', newInventoryController)
.name;

View file

@ -0,0 +1,17 @@
'use strict';
describe('Controller: NewInventoryCtrl', function() {
// load the controller's module
beforeEach(module('webAppApp.new_inventory'));
var NewInventoryCtrl;
// Initialize the controller and a mock scope
beforeEach(inject(function($controller) {
NewInventoryCtrl = $controller('NewInventoryCtrl', {});
}));
it('should ...', function() {
expect(1).to.equal(1);
});
});

View file

@ -0,0 +1,21 @@
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">New Inventory</h4>
</div>
<div class="modal-body">
<p class="form-group">
<label>Inventory Name</label>
<input type="text" ng-model="newInventory.name" class="form-control">
</p>
<div class="alert alert-info"> Inventory files should be named without an extension </div>
</div>
<div class="alert alert-danger" ng-if="err_msg">{{err_msg}}</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-disabled="!newInventory.name" ng-click="createInventory()">Create <span ng-if="createInventoryLoading" class="fa fa-spinner fa-spin"></span></button>
<button class="btn btn-default" type="button" ng-click="cancel()">Close</button>
</div>
</div>