UNPKG

knowhow-server

Version:

A personal workflow engine that can manage and use any network connected host

1,338 lines (1,165 loc) 42.5 kB
'use strict'; /* Controllers */ var myModule = angular.module('myApp.controllers', []). controller('AppCtrl', function ( $http, $scope, $modal) { $scope.serverInfo = {}; $scope.update_message = ""; $http({ method: 'GET', url: '/api/serverInfo' }). success(function (data, status, headers, config) { $scope.serverInfo = data; $scope.upgradeAvailable = ($scope.serverInfo.newestVersions && ($scope.serverInfo.version < $scope.serverInfo.newestVersions['knowhow-server'])); }). error(function (data, status, headers, config) { $scope.name = 'Error!'; }); }). controller('AboutController', function ( $http, $scope, $modal) { $scope.serverInfo = {}; $scope.update_message = ""; $http({ method: 'GET', url: '/api/serverInfo' }). success(function (data, status, headers, config) { $scope.serverInfo = data; }). error(function (data, status, headers, config) { $scope.name = 'Error!'; }); $scope.upgradeAvailable = ($scope.serverInfo.newestVersions && ($scope.serverInfo.version < $scope.serverInfo.newestVersions.knowhow-server)); var checkForUpdates = function() { console.log("checkiong for updates"); $scope.update_message = "checking for updates..." $http({ method: 'POST', url: '/api/checkForUpdates' }).success(function (data, status, headers, config) { $scope.serverInfo.newestVersions = data; $scope.upgradeAvailable = ($scope.serverInfo.newestVersions && ( $scope.serverInfo.version < $scope.serverInfo.newestVersions["knowhow-server"] || ($scope.serverInfo.installedVersions && $scope.serverInfo.installedVersions["knowhow"] < $scope.serverInfo.newestVersions["knowhow"]) || ($scope.serverInfo.installedVersions && $scope.serverInfo.installedVersions["knowhow-agent"] < $scope.serverInfo.newestVersions["knowhow-agent"]) || ($scope.serverInfo.installedVersions && $scope.serverInfo.installedVersions["knowhow-api"] < $scope.serverInfo.newestVersions["knowhow-api"]) || ($scope.serverInfo.installedVersions && $scope.serverInfo.installedVersions["knowhow-shell"] < $scope.serverInfo.newestVersions["knowhow-shell"]) ) ); $scope.update_message = ""; }). error(function (data, status, headers, config) { $scope.update_message = ""; }); } //checkForUpdates(); $scope.openUpgradeModal = function(serverInfo) { console.log(serverInfo); var modalInstance ={}; var upgradeController= function ($rootScope, $scope, $modal, $log, qs_repo) { $scope.serverInfo = serverInfo; $scope.upgradeServer = function(formData) { $scope.message = 'Upgrade In Progress'; $http.post('/upgrade/upgradeServer', { "sudoPwd": formData.sudoPassword} ). success(function(data) { $scope.connectedAgents = data; //location.reload(); modalInstance.dismiss('upgrade complete'); }).error(function(data, status, headers, config) { console.log(data); $scope.message="Unable to upgrade server: "+data.message; }); }; $scope.cancel = function () { console.log("nope I really don't want to do it"); modalInstance.dismiss('cancel'); }; }; modalInstance = $modal.open({ templateUrl: 'upgradeServer', controller: upgradeController, size: '' }); modalInstance.result.then(function (selectedItem) { //$scope.selected = selectedItem; }, function () { //$log.info('Modal dismissed at: ' + new Date()); }); } checkForUpdates(); }). controller('AddAgentController', function ($scope, $http, $location) { console.log('starting add agent controller'); $scope.master = {}; $scope.form = {}; $scope.test = ['sd','sdsds','dsdsd']; var socket = io(); socket.on('agent-update', function(agent){ console.log('agent update message received'); // var agent_status_box = document.getElementById(agent._id+'_status'); // var agent_message_box = document.getElementById(agent._id+'_messages'); // if (agent_message_box != undefined) { // agent_message_box.textContent = agent.message; // } // if (agent_status_box != undefined) { // agent_status_box.textContent = agent.status; getAgentList(); }); socket.on('agent-error', function(agent){ console.log('agent error message received'); // var agent_status_box = document.getElementById(agent._id+'_status'); // var agent_message_box = document.getElementById(agent._id+'_messages'); // if (agent_message_box != undefined) { // agent_message_box.textContent = agent.message; // } // if (agent_status_box != undefined) { // agent_status_box.textContent = agent.status; // } $scope.message = agent.message; getAgentList(); }); socket.on('agent-add', function(agent){ $http.get('/api/connectedAgents'). success(function(data) { $scope.connectedAgents = data; }); }); function getAgentList() { $http.get('/api/connectedAgents'). success(function(data) { $scope.connectedAgents = data; for(var index in data) {; if (data[index].agentUpgradeAvailable || data[index].shellUpgradeAvailable) { $scope.agentUpgradesAvailable = true; break; } } console.log("upgrade available ="+$scope.agentUpgradesAvailable); }); } getAgentList(); $scope.addAgent = function (agent) { $scope.message = undefined; $scope.master = angular.copy(agent); $http.post('/api/addAgent', agent). success(function(data) { $scope.connectedAgents = data; //location.reload(); }).error(function(data, status, headers, config) { $scope.message="Unable to start agent: "+data.message; }); }; $scope.deleteAgent = function (agent) { $scope.message = undefined; $http.post('/api/deleteAgent', agent). success(function(data) { $scope.connectedAgents = data; getAgentList(); }).error(function(data, status, headers, config) { getAgentList(); }); }; $scope.refreshAgent = function (agent) { console.log(agent); $scope.message = undefined; $http.post('/api/resetAgent', agent). success(function(data) { $scope.connectedAgents = data; getAgentList(); }); }; $scope.upgradeAgent = function(agent) { $scope.message = undefined; $scope.master = angular.copy(agent); $http.post('/upgrade/upgradeAgent',{"agent": agent}). success(function(data) { getAgentList(); //location.reload(); }).error(function(data, status, headers, config) { $scope.message="Unable to upgrade agent: "+data.message; }); } $scope.upgradeAllAgents = function() { $scope.message = undefined; $http.post('/upgrade/upgradeAllAgents'). success(function(data) { getAgentList(); //location.reload(); }).error(function(data, status, headers, config) { $scope.message="Unable to upgrade agent: "+data.message; getAgentList(); }); } $scope.tabs = [ { title:'Dynamic Title 1', content:'Dynamic content 1' }, { title:'Dynamic Title 2', content:'Dynamic content 2', disabled: true } ]; $scope.alertMe = function() { setTimeout(function() { alert('You\'ve selected the alert tab!'); }); }; }). controller('JobsController', function ($scope, $modal, $http, $timeout, $log, qs_repo, qs_agent) { $scope.runningJobs = {}; $scope.output=""; var loadJobs = function() { $http.get('/api/runningJobsList'). success(function(data) { $scope.runningJobs = data; }); }; loadJobs(); $scope.job_tabs = [ { title:'Edit ', content:'Edit', disabled: false }, { title:'Logs', content:'Logs', disabled: false } ]; var socket = io(); qs_agent.loadAgentList(function(agentList) { $scope.connectedAgents = agentList; console.log($scope.connectedAgents); qs_agent.listenForAgentEvents($scope, $scope.connectedAgents, socket); }); socket.on('job-update', function(agent,job){ //loadJobs(); updateRunningJobs(agent,job); $scope.$apply(); }); socket.on('job-start', function(agent,job){ console.log('job start message received'); if (agent && job && !$scope.runningJobs[agent._id]) { $scope.runningJobs[agent._id] = {}; } $scope.runningJobs[agent._id][job.id] = {} job.progress=0; updateRunningJobs(agent,job); $scope.message=job.id+" started"; $scope.$apply(); }); socket.on('job-complete', function(agent,job){ console.log('job complete message received'); job.progress=0; //updateRunningJobs(agent,job); if ($scope.runningJobs[agent._id] && $scope.runningJobs[agent._id][job.id]) { delete $scope.runningJobs[agent._id][job.id]; } $scope.message=job.id+" completed"; $scope.$apply(); }); socket.on('job-cancel', function(agent,job){ console.log('job cancel message received'); //updateRunningJobs(agent,job); if ($scope.runningJobs[agent._id] && $scope.runningJobs[agent._id][job.id]) { delete $scope.runningJobs[agent._id][job.id]; } $scope.message=job.id+" cancelled "+job.status; $scope.$apply(); }); socket.on('job-error', function(agent,job){ console.log('job error message received'); //updateRunningJobs(agent,job); if ($scope.runningJobs[agent._id] && $scope.runningJobs[agent._id][job.id]) { delete $scope.runningJobs[agent._id][job.id]; } if (job.status) { $scope.message="error "+job.id+": "+job.status; } $scope.$apply(); }); socket.on('execution-start', function(agent,command) { console.log("starting: "+command.command); $scope.$broadcast('generated-input', { input: true, text: command.command, breakLine: true, start: true }); $scope.scrollTerminalToBottom(); }); socket.on('execution-output', function(agent,command) { //$scope.runningJobs[agent._id].output+=command.output $scope.output+=command.command+"\n"; $scope.output+=command.output+"\n"; var output = []; output.push(command.output); $scope.$broadcast('terminal-output', { text: output, breakLine: false }); $scope.scrollTerminalToBottom(); }); socket.on('execution-error', function(agent,command) { console.log('execution error message received'); //$scope.runningJobs[agent._id].output+=command.output var output = []; output.push(command.output); $scope.$broadcast('terminal-output', { output: true, text: output, breakLine: true, error: true }); $scope.scrollTerminalToBottom(); }); $scope.clearOutput = function() { $scope.$broadcast('terminal-command', { 'command': 'clear' }); } $scope.scrollTerminalToBottom = function() { document.getElementById('terminal').scrollBottom }; var updateRunningJobs = function(agent,job) { if (agent && job && $scope.runningJobs[agent._id] && $scope.runningJobs[agent._id][job.id]) { $scope.runningJobs[agent._id][job.id].progress=job.progress; $scope.runningJobs[agent._id][job.id].status=job.status; $scope.runningJobs[agent._id][job.id].id=job.id; $scope.runningJobs[agent._id].agent={_id: agent._id, user: agent.user, host: agent.host, port: agent.port}; } }; $scope.toggled = function(open) { console.log('Dropdown is now: ', open); }; $scope.toggleDropdown = function($event) { $event.preventDefault(); $event.stopPropagation(); $scope.status.isopen = !$scope.status.isopen; }; $http.get('/repo/listRepositories'). success(function(data) { $scope.fileRepos = data; }); var options = { mode: 'code', modes: ['code', 'form', 'text', 'tree', 'view'], // allowed modes error: function (err) { console.log(err.toString); alert(err.toString()); } }; var container; var editor; $timeout(function() { container = document.getElementById('jsoneditor'); console.log('container='+container); if (container) { editor = new JSONEditor(container,options); } }, 1000); var tree_handler = function(branch) { //console.log(branch); console.log('selection='+branch.label+ ' navigating='+navigating+' ext='+branch.ext+' type='+branch.type); $scope.selectedFile = branch; $scope.message = undefined; if (branch.type == 'file') { qs_repo.loadFile($scope.selectedRepo, branch.path, function(err,data) { console.log("data="+data); if (branch.ext=='.json') { editor.setText(data); editor.setMode('code') } else { editor.setText(data); editor.setMode('text') } }); } $scope.assetURL = qs_repo.getFileRepoURL($scope.selectedRepo,branch.path); console.log("url="+ $scope.assetURL); }; //tree controls //$scope.addFile = addFile; $scope.deleteFile = function () { qs_repo.deleteFile($scope.selectedFile, false, function(err,data) { var deleted_branch = $scope.selectedFile; if (tree.get_parent_branch(deleted_branch)) { var parent_branch = tree.get_parent_branch(deleted_branch); tree.select_branch(parent_branch); var newChildren = []; var oldChildren = tree.get_children(parent_branch); for (var child in oldChildren) { console.log(child.path+" "+deleted_branch.path); if (oldChildren[child].path != deleted_branch.path) { newChildren.push(oldChildren[child]); } else { console.log("removing deleted branch from tree"); } } console.log(parent_branch); console.log(newChildren); parent_branch.children = newChildren; } else { $scope.selectRepo($scope.selectedRepoName); } }); }; $scope.jobs_tree_handler = tree_handler; $scope.saveJob = function() { if($scope.selectedFile) { qs_repo.saveFile($scope.selectedFile.path, editor.getText(), function(err, message) { $scope.message = message; }); } }; var jobs = [] ; var tree; $scope.job_tree = tree = {}; $scope.jobs = jobs; $scope.loading_jobs = false; $scope.addFile = function() { qs_repo.openNewFileModal($scope.selectedFile, $scope.selectedRepoName, tree,'addFile'); } $scope.selectAgent = function(agent) { $scope.selectedAgent = agent; console.log('selected agent: '+agent); $scope.status.isopen = !$scope.status.isopen; var selectAgent = document.getElementById('selectAgent'); selectAgent.textContent=agent.user+'@'+agent.host+':'+agent.port; $scope.$broadcast('terminal-command', { 'command': 'change-prompt', 'prompt': { 'user': selectAgent.textContent } }); }; $scope.selectRepo = function(selectedRepo) { console.log('selected repo: '+selectedRepo.label); $scope.selectedRepoName = selectedRepo.label; $scope.selectedRepo = selectedRepo; qs_repo.loadRepo(selectedRepo,'jobs',function(err, data) { if(err) { alert("unable to load repository"); } $scope.jobs=data; }); $scope.repoSelect.isopen = !$scope.repoSelect.isopen; var selectRepo = document.getElementById('selectRepo'); selectRepo.textContent=selectedRepo.label; $scope.selectedRepo=selectedRepo; }; var navigating = false; $scope.cancel = function(agent, job) { var data = { khAgent: agent, job: job }; $http({ method: 'POST', url: '/api/cancelJob', data: data }).success(function (data, status, headers, config) { $scope.agentInfo = data; $scope.message = job.id+' cancel request submitted to agent: '+agent.user+'@'+agent.host+':'+agent.port console.log("submitted job request"); }). error(function (data, status, headers, config) { $scope.message = data.message+' : '+status; }); }; $scope.execute = function() { if (!$scope.selectedAgent) { $scope.message='Please select an agent to execute'; return; } $scope.job_tabs[1].active=true //get the content from the json editor var job; try { job = editor.get(); //JSON.parse(jjob); } catch (e) { console.log('error getting job data: '+e.message); $scope.message=e.message; return; } var data = { khAgent: $scope.selectedAgent, job: job }; $http({ method: 'POST', url: '/api/execute', data: data }).success(function (data, status, headers, config) { $scope.agentInfo = data; loadJobs(); console.log("submitted job request"); $scope.message="submitted "+job.id+" to "+$scope.selectedAgent.host+":"+$scope.selectedAgent.port; //$scope.$apply(); }). error(function (data, status, headers, config) { $scope.message = data.message+' : '+status; //$scope.apply(); }); }; $scope.$on('terminal-input', function (e, consoleInput) { var cmd = consoleInput[0]; $scope.executeSingleCommand(cmd.command); }); $scope.executeSingleCommand = function(command) { console.log(command); var job = { "id": command, "options": { "noEcho": true }, "script": { "commands": [ { "command" : command } ] } } var data = { khAgent: $scope.selectedAgent, job: job }; $http({ method: 'POST', url: '/api/execute', data: data }).success(function (data, status, headers, config) { $scope.agentInfo = data; loadJobs(); console.log("submitted job request"); $scope.message="submitted "+job.id+" to "+$scope.selectedAgent.host+":"+$scope.selectedAgent.port; //$scope.$apply(); }). error(function (data, status, headers, config) { $scope.message = data.message+' : '+status; //$scope.apply(); }); }; }).controller('LogsController', function ($scope, $http) { var socket = io.connect(); var container = document.getElementById('log-container'); socket.on('new-data', function(data) { var message = JSON.parse(data.value); addMessage(message);//message.timestamp+':'+message.level+' '+message.message); }); $http({ method: 'POST', url: '/api/logs', data: { numLogs:20 } }). success(function (data, status, headers, config) { $scope.logs = data.file; for(var message in data.file) { addMessage(data.file[message]); } }); function addMessage(message) { var newDiv = document.createElement('div'); var logText=document.createTextNode(message.timestamp+':'+message.level+' '+message.message); newDiv.appendChild(logText); container.appendChild(newDiv); } }).controller('WorkflowsController', function ($scope, $modal, $http, $log, qs_repo, qs_workflow) { $scope.runningWorkflows = {}; var loadWorkflows = function() { $http.get('/api/runningWorkflowsList'). success(function(data) { $scope.runningJobs = data; }); }; loadWorkflows(); $http.get('/repo/listRepositories'). success(function(data) { $scope.fileRepos = data; }); var options = { mode: 'code', modes: ['code', 'form', 'text', 'tree', 'view'], // allowed modes error: function (err) { console.log(err.toString); alert(err.toString()); } }; var container = document.getElementById('jsoneditor'); var editor = new JSONEditor(container,options); var env_container; var env_editor; var workflows = [] ; var tree; $scope.workflow_tree = tree = {}; $scope.workflows = workflows; $scope.loading_workflows = false; var environments = [] ; $scope.environments_tree = {}; $scope.environments = environments; $scope.loading_environments = false; $scope.workflow = {}; $scope.environment = {}; var loadAgentsForEnvironment = function(environment) { console.log("loading agents..."); var data = { environment: environment }; $http({ method: 'POST', url: '/api/loadAgentsForEnvironment', data: data }).success(function(data) { console.log(data); qs_workflow.watchEnvironment(data); var socket = io(); qs_workflow.listenForAgentEvents($scope, socket); qs_workflow.listenForJobEvents($scope, socket); qs_workflow.listenForWorkflowEvents($scope, socket); $scope.environment = qs_workflow.watchedEnvironment; }).error(function(data) { if (data.message) { $scope.env_message = data.message; } if (data.environment) { $scope.environment = data.environment; } }); } $scope.initAgents = function(credentials) { console.log("init agents..."); console.log(credentials); $scope.master = angular.copy(credentials); var data = { credentials: credentials, environment: $scope.environment }; $http({ method: 'POST', url: '/api/initAgents', data: data }). success(function(data) { $scope.workflow.agents = data; }).error( function(data) { if (data.message) { $scope.env_message = data.message; } }); }; $scope.selectRepo = function(selectedRepo) { console.log('selected repo: '+selectedRepo.name); $scope.selectedRepo=selectedRepo qs_repo.loadRepo(selectedRepo,'environments',function(err, data) { if(err) { alert("unable to load repository"); } if (!env_container) { env_container = document.getElementById('env_editor'); console.log('env_container='+env_container); env_editor = new JSONEditor(env_container,options); } $scope.environments=data; qs_repo.loadRepo(selectedRepo,'workflows',function(err, data) { if(err) { alert("unable to load repository"); } $scope.workflows=data; }); }); $scope.repoSelect.isopen = !$scope.repoSelect.isopen; var selectRepo = document.getElementById('selectRepo'); selectRepo.textContent=selectedRepo.label; }; $scope.toggled = function(open) { console.log('Dropdown is now: ', open); }; $scope.toggleDropdown = function($event) { $event.preventDefault(); $event.stopPropagation(); $scope.status.isopen = !$scope.status.isopen; }; $scope.addEnv = function() { qs_repo.openNewFileModal( $scope.selectedEnvBranch, $scope.selectedRepoName, $scope.environments_tree, 'addFile'); } $scope.deleteEnv = function () { qs_repo.deleteFile($scope.selectedEnvBranch, false, function(err,data) { var deleted_branch = $scope.selectedEnvBranch; if ( $scope.environments_tree.get_parent_branch(deleted_branch)) { var parent_branch = $scope.environments_tree.get_parent_branch(deleted_branch); $scope.environments_tree.select_branch(parent_branch); var newChildren = []; var oldChildren = $scope.environments_tree.get_children(parent_branch); for (var child in oldChildren) { console.log(child.path+" "+deleted_branch.path); if (oldChildren[child].path != deleted_branch.path) { newChildren.push(oldChildren[child]); } else { console.log("removing deleted branch from tree"); } } console.log(parent_branch); console.log(newChildren); parent_branch.children = newChildren; } else { $scope.selectRepo($scope.selectedRepoName); } }); }; $scope.addFile = function() { qs_repo.openNewFileModal($scope.selectedFile, $scope.selectedRepoName, tree, 'addFile'); } $scope.deleteFile = function () { qs_repo.deleteFile($scope.selectedFile, false, function(err,data) { var deleted_branch = $scope.selectedFile; if (tree.get_parent_branch(deleted_branch)) { var parent_branch = tree.get_parent_branch(deleted_branch); tree.select_branch(parent_branch); var newChildren = []; var oldChildren = tree.get_children(parent_branch); for (var child in oldChildren) { console.log(child.path+" "+deleted_branch.path); if (oldChildren[child].path != deleted_branch.path) { newChildren.push(oldChildren[child]); } else { console.log("removing deleted branch from tree"); } } console.log(parent_branch); console.log(newChildren); parent_branch.children = newChildren; } else { $scope.selectRepo($scope.selectedRepoName); } }); }; var navigating = false; $scope.tree_handler = function(branch) { //console.log(branch); console.log('selection='+branch.label+ ' navigating='+navigating+' ext='+branch.ext+' type='+branch.type); $scope.selectedFile = branch; $scope.message = undefined; $scope.env_message = undefined; console.log("url="+ $scope.assetURL); if (branch.type == 'file') { qs_repo.loadFile($scope.selectedRepo.label, branch.path, function(err,data) { //console.log("data="+data); if (branch.ext=='.json') { editor.setText(data); editor.setMode('code'); } else { editor.setMode('text'); editor.setText(data); } $scope.workflowURL=qs_repo.getFileRepoURL($scope.selectedRepo,branch.path); }); } }; $scope.env_tabs = [ { title:'Connect ', content:'Connect ', disabled: false }, { title:'Edit', content:'Edit', disabled: false } ]; $scope.env_tree_handler = function(branch) { //console.log(branch); console.log('selection='+branch.label+ ' navigating='+navigating+' ext='+branch.ext+' type='+branch.type); $scope.env_message = undefined; $scope.selectedEnvBranch = branch; if (branch.type == 'file') { qs_repo.loadFile($scope.selectedRepo.label, branch.path, function(err,data) { //console.log("data="+data); if (branch.label=='environment.json') { $scope.env_tabs[0].active = true $scope.selectedEnv = branch; env_editor.setMode('text'); var environment = JSON.parse(data) loadAgentsForEnvironment(environment); env_editor.set(environment); $scope.env_tabs[0].title = 'connect '+environment.id; $scope.env_tabs[1].title = 'Edit '+$scope.selectedEnvBranch.label; } else { console.log("loading text") env_editor.setMode('text'); env_editor.setText(data); $scope.env_tabs[1].title = 'Edit '+$scope.selectedEnvBranch.label; $scope.env_tabs[1].active = true } }); $scope.environmentURL=qs_repo.getFileRepoURL($scope.selectedRepo,branch.path); } }; //tree controls //$scope.addFile = addFile; $scope.deleteFile = function () { qs_repo.deleteFile($scope.selectedFile, false, function(err,data) { var deleted_branch = $scope.selectedFile; if (tree.get_parent_branch(deleted_branch)) { var parent_branch = tree.get_parent_branch(deleted_branch); tree.select_branch(parent_branch); var newChildren = []; var oldChildren = tree.get_children(parent_branch); for (var child in oldChildren) { console.log(child.path+" "+deleted_branch.path); if (oldChildren[child].path != deleted_branch.path) { newChildren.push(oldChildren[child]); } else { console.log("removing deleted branch from tree"); } } console.log(parent_branch); console.log(newChildren); parent_branch.children = newChildren; } else { $scope.selectRepo($scope.selectedRepoName); } }); }; $scope.saveWorkflow = function() { if($scope.selectedFile) { try { qs_repo.saveFile($scope.selectedFile.path, editor.get(), function(err, message) { $scope.message = message; }); } catch(err) { $scope.message = err.message } } }; $scope.saveEnv = function() { if ($scope.selectedEnv && $scope.selectedEnvBranch.ext=='.json') { try { JSON.parse(env_editor.getText()); } catch(err) { console.log(err); //console.log(env_editor.get()); $scope.env_message = "JSON must be valid before saving: "+err.message; return; } } console.log("saving env file"); qs_repo.saveFile($scope.selectedEnvBranch.path, env_editor.getText(), function(err, message) { $scope.env_message = message; if ($scope.selectedEnvBranch.label=='environment.json') { $scope.env_tabs[0].active = true env_editor.setMode('text'); var environment = JSON.parse(env_editor.getText()) loadAgentsForEnvironment(environment); env_editor.set(environment); $scope.env_tabs[0].title = 'connect '+environment.id; $scope.env_tabs[1].title = 'Edit '+$scope.selectedEnvBranch.label; } }); }; $scope.executeWorkflow = function() { if (!qs_workflow.checkAgents()) { $scope.message='Please connect all agents before attempting a workflow'; return; } $scope.message=''; //get the content from the json editor var workflow; try { workflow = editor.get(); //JSON.parse(jjob); } catch (e) { console.log('error loading workflow.') $scope.message='Invalid JSON - please fix.'; return; } var data = { environment: $scope.environment, workflow: workflow }; $http({ method: 'POST', url: '/api/executeWorkflow', data: data }).success(function (data, status, headers, config) { $scope.agentInfo = data; console.log("submitted workflow request"); $scope.message = "executing workflow"; }). error(function (data, status, headers, config) { $scope.message = data.message+' : '+status; //$scope.message = 'Unable to contact server http status: '+status; }); }; $scope.cancel = function(agent, job) { var data = { khAgent: agent, job: job }; $http({ method: 'POST', url: '/api/cancelWorkflow', data: data }).success(function (data, status, headers, config) { $scope.agentInfo = data; $scope.message = job.id+' cancel request submitted to agent: '+$scope.selectedAgent.user+'@'+$scope.selectedAgent.host+':'+$scope.selectedAgent.port console.log("submitted job request"); }). error(function (data, status, headers, config) { $scope.message = data.message+' : '+status; }); }; }).controller('RepositoriesController', function ($scope, $modal, $http, $log, $timeout, qs_repo, $upload) { $scope.repoData = []; $scope.repoTree = {}; $http({ method: 'GET', url: '/api/serverInfo' }). success(function (data, status, headers, config) { $scope.serverInfo = data; $scope.newRepo = { name: 'MyRepo', path: $scope.serverInfo.workingDir+'/MyRepo' }; }). error(function (data, status, headers, config) { $scope.serverInfo = {}; $scope.newRepo = { name: 'MyRepo', path: '/tmp/MyRepo' }; }); var loadRepos = function() { $http.get('/repo/listRepositories'). success(function(data) { $scope.repoData = data; }); }; loadRepos(); var options = { mode: 'code', modes: ['code', 'form', 'text', 'tree', 'view'], // allowed modes error: function (err) { console.log(err.toString); alert(err.toString()); } }; var repo_container, repo_editor; $timeout(function() { repo_container = document.getElementById('jsoneditor'); console.log('repo_container='+repo_container); if (repo_container) { repo_editor = new JSONEditor(repo_container,options); } }, 1000); $scope.repo_tabs = [ { title:'Edit File', content:'Edit', disabled: false }, { title:'Edit Repo', content:'Edit Repo', disabled: false }, { title:'New Repository', content:'New Repository', active: true, disabled: false } ]; $scope.repo_message = undefined; $scope.repo_tree_handler = function(branch) { console.log(branch); console.log('selection='+branch.label+ ' ext='+branch.ext+' type='+branch.type); $scope.currentFile = branch; if (branch.type == 'repo') { $scope.selectedRepo = branch; qs_repo.loadRepo(branch,'',function(err, data) { if(err) { alert("unable to load repository: "+err.message); } console.log(data); branch.children=data[0].children; //$scope.repoTree.expand_branch(branch); $scope.repo_tabs[1].title = 'Edit Repo '+branch.label; $scope.repo_tabs[1].active = true }); console.log("loading repo"); } else if (branch.type == 'file') { $scope.selectedFile = branch; qs_repo.loadFile($scope.selectedRepo, branch.path, function(err,data) { //console.log("data="+data); console.log("loading text"); repo_editor.setMode('text'); repo_editor.setText(data); $scope.repo_tabs[0].title = 'Edit '+branch.label; $scope.repo_tabs[0].active = true }); } }; $scope.addRepo = function(newRepo) { qs_repo.addRepo(newRepo,function(err, addedRepo) { if (err) { $scope.repo_message="unable to create repo: "+err.message return; } loadRepos(); //$scope.repoTree.select_branch(addedRepo); $scope.repo_message="repo: "+addedRepo.name+" created."; }); } $scope.updateRepo = function(existingRepo) { qs_repo.updateRepo(existingRepo,function(err, updatedRepo) { if (err) { $scope.repo_message="unable to update repo: "+err.message return; } loadRepos(); $scope.repoTree.select_branch(updatedRepo); $scope.repo_message="repo: "+updatedRepo.name+" updated."; }); } $scope.addFile = function() { qs_repo.openNewFileModal($scope.currentFile, $scope.selectedRepoName, $scope.repoTree,'addFile'); } $scope.deleteFile = function() { if ($scope.currentFile) { if ($scope.currentFile.label == 'jobs' || $scope.currentFile.label == 'environments' || $scope.currentFile.label == 'workflows') { $scope.repo_message="cannot delete environments, jobs, or workflows directories."; return; } var type = $scope.currentFile.type; var repoName = $scope.currentFile.label; var deleted_branch = { _id: $scope.currentFile._id, type: $scope.currentFile.type, label: $scope.currentFile.label, name: $scope.currentFile.label, path: $scope.currentFile.path }; console.log(deleted_branch); qs_repo.deleteFile(deleted_branch, false, function(err,data) { var repoTree = $scope.repoTree; if (err) { $scope.repo_message="unable to delete repo: "+err.message return; } if (type == "repo") { loadRepos(); //repoTree.select_branch(addedRepo); $scope.repo_message="repo: "+repoName+" deleted."; $scope.selectedRepo=undefined; $scope.repo_tabs[2].active = true } else if (repoTree.get_parent_branch(deleted_branch)) { var parent_branch = repoTree.get_parent_branch(deleted_branch); repoTree.select_branch(parent_branch); var newChildren = []; var oldChildren = tree.get_children(parent_branch); for (var child in oldChildren) { console.log(child.path+" "+deleted_branch.path); if (oldChildren[child].path != deleted_branch.path) { newChildren.push(oldChildren[child]); } else { console.log("removing deleted branch from tree"); } } console.log(parent_branch); console.log(newChildren); parent_branch.children = newChildren; } }); } } $scope.onFileSelect = function($files, newRepo) { //$files: an array of files selected, each file has name, size, and type. var re = new RegExp('/', 'g'); /* var createRepo = { path: newRepo.path.replace(re,'~'), name: newRepo.name }*/ var createRepo = newRepo.path.replace(re,'~')+','+newRepo.name; console.log(createRepo); for (var i = 0; i < $files.length; i++) { var file = $files[i]; $scope.upload = $upload.upload({ url: '/repo/uploadRepoTarBall', //upload.php script, node.js route, or servlet url //method: 'POST' or 'PUT', //headers: {'header-key': 'header-value'}, //withCredentials: true, //data: {newRepo: newRepo}, file: file, // or list of files ($files) for html5 only fileName: JSON.stringify(createRepo),//'doc.jpg' or ['1.jpg', '2.jpg', ...] // to modify the name of the file(s) // customize file formData name ('Content-Disposition'), server side file variable name. //fileFormDataName: myFile, //or a list of names for multiple files (html5). Default is 'file' // customize how data is added to formData. See #40#issuecomment-28612000 for sample code //formDataAppender: function(formData, key, val){} }).progress(function(evt) { $scope.uploadProgress = parseInt(100.0 * evt.loaded / evt.total); console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total)); }).success(function(data, status, headers, config) { console.log(data); loadRepos(); //$scope.repoTree.select_branch(data); $scope.repo_message="repo: "+ newRepo.name+" imported from "+newRepo.fileName; $scope.uploadProgress = undefined; }).error(function(data, status, headers, config) { $scope.repo_message="unable to import repo: "+data; console.log(data); console.log(headers); console.log(config); $scope.uploadProgress = undefined; }); //.then(success, error, progress); // access or attach event listeners to the underlying XMLHttpRequest. //.xhr(function(xhr){xhr.upload.addEventListener(...)}) } /* alternative way of uploading, send the file binary with the file's content-type. Could be used to upload files to CouchDB, imgur, etc... html5 FileReader is needed. It could also be used to monitor the progress of a normal http post/put request with large data*/ // $scope.upload = $upload.http({...}) see 88#issuecomment-31366487 for sample code. }; $scope.downloadTarBall = function(repo) { var data = { repo: repo, }; $http({ method: 'POST', url: '/repo/downloadRepoTarBall', data: data }).success(function (data, status, headers, config) { console.log("got tarball"); }). error(function (data, status, headers, config) { $scope.repo_message="unable to download: "+data; }); } $scope.importFromHost = function(newRepo) { if (!newRepo.name || !newRepo.path) { $scope.repo_message="Repo name and file path must be defined."; return; } var data = { newRepo: newRepo, } $scope.repo_message="importing..."; $http({ method: 'POST', url: '/repo/importRepoFromServer', data: data }).success(function (data, status, headers, config) { loadRepos(); //$scope.repoTree.select_branch(data); $scope.repo_message="repo: "+ newRepo.name+" imported from: "+newRepo.host+":"+newRepo.port; }). error(function (data, status, headers, config) { $scope.repo_message="unable to import repo: "+data; }); } $scope.importFromGIT = function(newRepo) { if (!newRepo.name || !newRepo.path) { $scope.repo_message="Repo name and file path must be defined."; return; } var data = { newRepo: newRepo, } $scope.repo_message="importing..."; $http({ method: 'POST', url: '/repo/importRepoFromGIT', data: data }).success(function (data, status, headers, config) { loadRepos(); //$scope.repoTree.select_branch(data); $scope.repo_message="repo: "+ newRepo.name+" imported from: "+newRepo.gitRepo; }). error(function (data, status, headers, config) { $scope.repo_message="unable to import repo: "+data; }); } $scope.saveFile = function() { if($scope.selectedFile) { qs_repo.saveFile($scope.currentFile.path, editor.get(), function(err, message) { $scope.message = message; }); } }; });