'use strict'; const angular = require('angular'); /*@ngInject*/ export function ansibleService($http,YAML,Projects) { // AngularJS will instantiate a singleton by calling "new" on this function // AngularJS will instantiate a singleton by calling "new" on this function var AnsibleService = this; var uri = '/api/ansible/'; var emptyPlaybookContent = '---\n# Playbook File -'; var defaultTaskProperties = ["variables","tags","name","notify","with_items","first_available_file","only_if","user","sudo","connection","when","register","ignore_errors","selected","changed_when","delegate_to","vars","poll","async","args","with_together"]; AnsibleService.modules = {}; this.getAnsibleModules = function(successCallback,errorCallback,parent,refresh){ if(!refresh && AnsibleService.modules[Projects.selectedProject.ansibleEngine.ansibleHost]) return successCallback(AnsibleService.modules[Projects.selectedProject.ansibleEngine.ansibleHost]); try{ if(!refresh && JSON.parse(localStorage['modules_' + Projects.selectedProject.ansibleEngine.ansibleHost])) return successCallback(JSON.parse(localStorage['modules_' + Projects.selectedProject.ansibleEngine.ansibleHost])); }catch(e){ //console.error(e) } $http.post(uri + 'modules',{ansibleEngine:Projects.selectedProject.ansibleEngine}).then(function(response){ var result = response.data.split('\n'); AnsibleService.modules[Projects.selectedProject.ansibleEngine.ansibleHost] = result.map(function(item){ return {"name" : item.split(" ")[0], "description": item.split(/ (.+)?/)[1]} }); localStorage['modules_' + Projects.selectedProject.ansibleEngine.ansibleHost] = JSON.stringify(AnsibleService.modules[Projects.selectedProject.ansibleEngine.ansibleHost]); successCallback(AnsibleService.modules[Projects.selectedProject.ansibleEngine.ansibleHost]) },errorCallback) }; this.getAnsibleModuleDescription = function(moduleName, successCallback,errorCallback,refresh){ try{ if(!refresh && JSON.parse(localStorage['module_description_' + Projects.selectedProject.ansibleEngine.ansibleHost + '_' + moduleName])) return successCallback(JSON.parse(localStorage['module_description_' + Projects.selectedProject.ansibleEngine.ansibleHost + '_' + moduleName])); }catch(e){ } var command = 'ansible-doc ' + moduleName; if(Projects.selectedProject.ansibleEngine.customModules){ command = 'export ANSIBLE_LIBRARY="' + Projects.selectedProject.ansibleEngine.customModules + '"; ' + command; } $http.post(uri + 'command',{ansibleEngine:Projects.selectedProject.ansibleEngine,command:command}) .then(function(response){ localStorage['module_description_' + Projects.selectedProject.ansibleEngine.ansibleHost + '_' + moduleName] = JSON.stringify(response.data); successCallback(response.data) },errorCallback) }; this.executeAnsiblePlayBook = function(body,successCallback,errorCallback,parent){ $http.post(uri + 'execute',body).then(successCallback,errorCallback) }; this.executeCommand = function(command, successCallback,errorCallback){ $http.post(uri + 'command',{command:command,ansibleEngine:Projects.selectedProject.ansibleEngine}).then(successCallback,errorCallback) }; this.getLogs = function(executionData,successCallback,errorCallback){ $http.get(uri+'logs/'+executionData._id).then(successCallback,errorCallback); }; this.query = function(successCallback,errorCallback){ $http.get(uri).then(successCallback,errorCallback); }; this.getModuleFromTask = function(task){ var module = null; angular.forEach(JSON.parse(angular.toJson(task)), function(value, key) { if(defaultTaskProperties.indexOf(key) < 0){ module = key } }); if(module === 'include' && !task.tags && task.include.indexOf('tags') > -1){ task.tags = task.include.replace(/.*tags=(.*)/,"$1") } return module; }; // -------------------------- PROJECT ------------------------- this.getProjectFiles = function(successCallback,errorCallback){ $http.post(uri + 'project/files',{ansibleEngine:Projects.selectedProject.ansibleEngine}).then(successCallback,errorCallback) }; // -------------------------- PLAYBOOK ------------------------- this.getPlaybookList = function(successCallback,errorCallback){ $http.post(uri + 'playbook/list',{ansibleEngine:Projects.selectedProject.ansibleEngine}).then(successCallback,errorCallback) }; this.deletePlaybook = function(playbookName,successCallback,errorCallback){ $http.post(uri + 'playbook/delete',{ansibleEngine:Projects.selectedProject.ansibleEngine,playbookName:playbookName}).then(successCallback,errorCallback) }; this.createPlaybook = function(playbookName,playbookFileContents,successCallback,errorCallback){ var playbookContent = playbookFileContents || (emptyPlaybookContent + playbookName); $http.post(uri + 'playbook/create',{ansibleEngine:Projects.selectedProject.ansibleEngine,playbookName:playbookName,playbookFileContents:playbookContent}).then(successCallback,errorCallback) }; this.readPlaybook = function(playbookName,successCallback,errorCallback){ $http.post(uri + 'playbook/get',{ansibleEngine:Projects.selectedProject.ansibleEngine,playbookName:playbookName}).then(successCallback,errorCallback) }; this.readPlaybookData = function(playbookData){ return YAML.parse(playbookData) }; // -------------------------- ROLES ------------------------- this.getRoleList = function(successCallback,errorCallback){ $http.post(uri + 'roles/list',{ansibleEngine:Projects.selectedProject.ansibleEngine}).then(successCallback,errorCallback) }; this.searchRolesGalaxy = function(searchText,successCallback,errorCallback){ $http.post(uri + 'roles/search/galaxy',{searchText:searchText,ansibleEngine:Projects.selectedProject.ansibleEngine}).then(successCallback,errorCallback) }; this.searchRolesGithub = function(searchText,successCallback,errorCallback){ $http.post(uri + 'roles/search/github',{searchText:searchText,ansibleEngine:Projects.selectedProject.ansibleEngine}).then(successCallback,errorCallback) }; this.createRole = function(roleName,successCallback,errorCallback,selectedRoleName){ $http.post(uri + 'roles/create',{roleName:roleName,selectedRoleName:selectedRoleName,ansibleEngine:Projects.selectedProject.ansibleEngine}).then(successCallback,errorCallback) }; this.importRole = function(roleType,roleNameUri,successCallback,errorCallback){ $http.post(uri + 'roles/import',{roleType:roleType,roleNameUri:roleNameUri,ansibleEngine:Projects.selectedProject.ansibleEngine}).then(successCallback,errorCallback) }; this.deleteRole = function(roleName,successCallback,errorCallback){ $http.post(uri + 'roles/delete',{roleName:roleName,ansibleEngine:Projects.selectedProject.ansibleEngine}).then(successCallback,errorCallback) }; this.getRoleFiles = function(roleName,successCallback,errorCallback){ $http.post(uri + 'roles/files',{roleName:roleName,ansibleEngine:Projects.selectedProject.ansibleEngine}).then(successCallback,errorCallback) }; // -------------------------- FILES ------------------------- this.createFile = function(fileAbsolutePath,successCallback,errorCallback,selectedFileName){ $http.post(uri + 'files/create',{fileAbsolutePath:fileAbsolutePath,selectedFileName:selectedFileName,ansibleEngine:Projects.selectedProject.ansibleEngine}).then(successCallback,errorCallback) }; this.updateFile = function(fileAbsolutePath,fileContents,successCallback,errorCallback,selectedFileName){ $http.post(uri + 'files/update',{fileAbsolutePath:fileAbsolutePath,fileContents:fileContents,selectedFileName:selectedFileName,ansibleEngine:Projects.selectedProject.ansibleEngine}).then(successCallback,errorCallback) }; this.deleteFile = function(fileAbsolutePath,successCallback,errorCallback,selectedFileName){ $http.post(uri + 'files/delete',{fileAbsolutePath:fileAbsolutePath,selectedFileName:selectedFileName,ansibleEngine:Projects.selectedProject.ansibleEngine}).then(successCallback,errorCallback) }; // -------------------------- INVENTORY ------------------------- this.getInventoryList = function(successCallback,errorCallback, projectFolder){ // Override project folder for other cases, such as roles var ansibleEngine = Projects.selectedProject.ansibleEngine; if(projectFolder){ ansibleEngine = angular.copy(Projects.selectedProject.ansibleEngine); ansibleEngine.projectFolder = projectFolder } $http.post(uri + 'inventory/list',{ansibleEngine:ansibleEngine}).then(successCallback,errorCallback) }; this.readInventory = function(inventoryName,successCallback,errorCallback){ $http.post(uri + 'inventory/get',{inventoryName:inventoryName,ansibleEngine:Projects.selectedProject.ansibleEngine}).then(successCallback,errorCallback) }; this.deleteInventory = function(inventoryName,successCallback,errorCallback){ $http.post(uri + 'inventory/delete',{ansibleEngine:Projects.selectedProject.ansibleEngine,inventoryName:inventoryName}).then(successCallback,errorCallback) }; this.createInventory = function(inventoryName,inventoryFileContents,successCallback,errorCallback){ $http.post(uri + 'inventory/create',{ansibleEngine:Projects.selectedProject.ansibleEngine,inventoryName:inventoryName,inventoryFileContents:inventoryFileContents}).then(successCallback,errorCallback) }; // -------------------------- Variable Files ------------------------- this.getVars = function(inventoryFileName, hostName, successCallback,errorCallback){ $http.post(uri + 'vars/hosts/get',{ansibleEngine:Projects.selectedProject.ansibleEngine,hostName:hostName,inventoryFileName:inventoryFileName}).then(successCallback,errorCallback) }; this.getRoleVars = function(roleName, successCallback,errorCallback){ $http.post(uri + 'vars/roles/get',{ansibleEngine:Projects.selectedProject.ansibleEngine,roleName:roleName}).then(successCallback,errorCallback) }; this.updateGroupVarsFile = function(groupName,groupVarsContents,successCallback,errorCallback){ $http.post(uri + 'vars_file/groups/update',{ansibleEngine:Projects.selectedProject.ansibleEngine,groupName:groupName,groupVarsContents:groupVarsContents}).then(successCallback,errorCallback) }; this.getGroupVarsFile = function(groupName,successCallback,errorCallback){ $http.post(uri + 'vars_file/groups/get',{ansibleEngine:Projects.selectedProject.ansibleEngine,groupName:groupName}).then(successCallback,errorCallback) }; this.updateHostVarsFile = function(hostName,hostVarsContents,successCallback,errorCallback){ $http.post(uri + 'vars_file/hosts/update',{ansibleEngine:Projects.selectedProject.ansibleEngine,hostName:hostName,hostVarsContents:hostVarsContents}).then(successCallback,errorCallback) }; this.getHostVarsFile = function(hostName,successCallback,errorCallback){ $http.post(uri + 'vars_file/hosts/get',{ansibleEngine:Projects.selectedProject.ansibleEngine,hostName:hostName}).then(successCallback,errorCallback) }; // ------------------- TAGS LIST -------------------------- this.getTagList = function(selectedPlaybook,inventory_file_name,ansibleEngine,successCallback,errorCallback){ $http.post(uri + 'tags/list',{ansibleEngine:ansibleEngine,inventory_file_name:inventory_file_name,selectedPlaybook:selectedPlaybook}).then(successCallback,errorCallback) }; // ------------- SOME HELPER FUNCTIONS -------------- this.parseINIString = function(data){ var regex = { section: /^\s*\[\s*([^\]]*)\s*\]\s*$/, param: /^\s*([\w\.\-\_]+).*$/, comment: /^\s*;.*$/ }; var hosts = []; var groups = []; var lines = data.split(/\r\n|\r|\n/); var group = null; group = {'name':'Un grouped', 'members': [], 'type': 'default'}; groups.push(group); // groups.push({'name':'All Hosts', 'members': hosts, 'type': 'default'}); lines.forEach(function(line){ if(regex.comment.test(line)){ return; }else if(regex.param.test(line)){ var match = line.match(regex.param); var host = match[1]; if(hosts.indexOf(host) < 0){ hosts.push(host); } if(group && group.members.indexOf(host) < 0){ group.members.push(host); } }else if(regex.section.test(line)){ var match = line.match(regex.section); group = {'name':match[1], 'members': [], 'type': 'userdefined'}; groups.push(group); } }); return {'hosts':hosts,'groups':groups}; }; this.jsonToAnsibleInventoryIni = function(inventoryData){ var name = inventoryData.name; var hosts = inventoryData.hosts; var groups = inventoryData.groups; var result_lines = ['# Inventory File - ' + name, '']; angular.forEach(groups,function(group){ if(group.name == 'All Hosts')return; if(group.name !== 'Un grouped'){ result_lines.push(''); result_lines.push('[' + group.name + ']'); } angular.forEach(group.members,function(member){ result_lines.push(member); }) }); return result_lines.join('\n') } } export default angular.module('webAppApp.ansible', []) .service('ansible', ansibleService) .name;