mirror of
https://github.com/ansible/awx.git
synced 2026-01-16 04:10:44 -03:30
Merge remote branch 'origin/master'
This commit is contained in:
commit
5d22ebd5b5
BIN
awx/.DS_Store
vendored
Normal file
BIN
awx/.DS_Store
vendored
Normal file
Binary file not shown.
@ -1118,8 +1118,8 @@ class JobEvent(models.Model):
|
||||
return None
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
self.failed = bool(self.event in self.FAILED_EVENTS)
|
||||
# FIXME: Propagage failed flag to parent events.
|
||||
if self.event in self.FAILED_EVENTS:
|
||||
self.failed = True
|
||||
try:
|
||||
if not self.host and self.event_data.get('host', ''):
|
||||
self.host = self.job.inventory.hosts.get(name=self.event_data['host'])
|
||||
@ -1129,9 +1129,18 @@ class JobEvent(models.Model):
|
||||
self.task = self.event_data.get('task', '')
|
||||
self.parent = self._find_parent()
|
||||
super(JobEvent, self).save(*args, **kwargs)
|
||||
self.update_parent_failed()
|
||||
self.update_hosts()
|
||||
self.update_host_summary_from_stats()
|
||||
|
||||
def update_parent_failed(self):
|
||||
# Propagage failed flag to parent events.
|
||||
if self.failed and self.parent and not self.parent.failed:
|
||||
p = self.parent
|
||||
p.failed = True
|
||||
p.save()
|
||||
p.update_parent_failed()
|
||||
|
||||
def update_hosts(self, extra_hosts=None):
|
||||
extra_hosts = extra_hosts or []
|
||||
hostnames = set()
|
||||
|
||||
@ -432,7 +432,7 @@ class JobEventSerializer(BaseSerializer):
|
||||
model = JobEvent
|
||||
fields = ('id', 'url', 'created', 'job', 'event', 'event_display',
|
||||
'event_data', 'failed', 'host', 'related', 'summary_fields',
|
||||
'parent')
|
||||
'parent', 'play', 'task')
|
||||
|
||||
def get_related(self, obj):
|
||||
res = super(JobEventSerializer, self).get_related(obj)
|
||||
|
||||
@ -213,6 +213,53 @@ class RunJobTest(BaseCeleryTest):
|
||||
'expected no traceback, got:\n%s' %
|
||||
job.result_traceback)
|
||||
|
||||
def check_job_events(self, job, runner_status='ok', plays=1, tasks=1):
|
||||
job_events = job.job_events.all()
|
||||
for job_event in job_events:
|
||||
unicode(job_event) # For test coverage.
|
||||
job_event.save()
|
||||
should_be_failed = bool(runner_status not in ('ok', 'skipped'))
|
||||
host_pks = set([self.host.pk])
|
||||
qs = job_events.filter(event='playbook_on_start')
|
||||
self.assertEqual(qs.count(), 1)
|
||||
for evt in qs:
|
||||
self.assertFalse(evt.host, evt)
|
||||
self.assertFalse(evt.play, evt)
|
||||
self.assertFalse(evt.task, evt)
|
||||
self.assertEqual(evt.failed, should_be_failed)
|
||||
self.assertEqual(set(evt.hosts.values_list('pk', flat=True)),
|
||||
host_pks)
|
||||
qs = job_events.filter(event='playbook_on_play_start')
|
||||
self.assertEqual(qs.count(), plays)
|
||||
for evt in qs:
|
||||
self.assertFalse(evt.host, evt)
|
||||
self.assertTrue(evt.play, evt)
|
||||
self.assertFalse(evt.task, evt)
|
||||
self.assertEqual(evt.failed, should_be_failed)
|
||||
self.assertEqual(set(evt.hosts.values_list('pk', flat=True)),
|
||||
host_pks)
|
||||
qs = job_events.filter(event='playbook_on_task_start')
|
||||
self.assertEqual(qs.count(), tasks)
|
||||
for evt in qs:
|
||||
self.assertFalse(evt.host, evt)
|
||||
self.assertTrue(evt.play, evt)
|
||||
self.assertTrue(evt.task, evt)
|
||||
self.assertEqual(evt.failed, should_be_failed)
|
||||
self.assertEqual(set(evt.hosts.values_list('pk', flat=True)),
|
||||
host_pks)
|
||||
qs = job_events.filter(event=('runner_on_%s' % runner_status))
|
||||
self.assertEqual(qs.count(), tasks)
|
||||
for evt in qs:
|
||||
self.assertEqual(evt.host, self.host)
|
||||
self.assertTrue(evt.play, evt)
|
||||
self.assertTrue(evt.task, evt)
|
||||
self.assertEqual(evt.failed, should_be_failed)
|
||||
self.assertEqual(set(evt.hosts.values_list('pk', flat=True)),
|
||||
host_pks)
|
||||
qs = job_events.filter(event__startswith='runner_')
|
||||
qs = qs.exclude(event=('runner_on_%s' % runner_status))
|
||||
self.assertEqual(qs.count(), 0)
|
||||
|
||||
def test_run_job(self):
|
||||
self.create_test_project(TEST_PLAYBOOK)
|
||||
job_template = self.create_test_job_template()
|
||||
@ -223,17 +270,7 @@ class RunJobTest(BaseCeleryTest):
|
||||
self.assertEqual(job.status, 'pending')
|
||||
job = Job.objects.get(pk=job.pk)
|
||||
self.check_job_result(job, 'successful')
|
||||
job_events = job.job_events.all()
|
||||
for job_event in job_events:
|
||||
unicode(job_event) # For test coverage.
|
||||
job_event.save()
|
||||
self.assertEqual(job_events.filter(event='playbook_on_start').count(), 1)
|
||||
self.assertEqual(job_events.filter(event='playbook_on_play_start').count(), 1)
|
||||
self.assertEqual(job_events.filter(event='playbook_on_task_start').count(), 2)
|
||||
self.assertEqual(job_events.filter(event='runner_on_ok').count(), 2)
|
||||
for evt in job_events.filter(event='runner_on_ok'):
|
||||
self.assertEqual(evt.host, self.host)
|
||||
self.assertEqual(job_events.filter(event='playbook_on_stats').count(), 1)
|
||||
self.check_job_events(job, 'ok', 1, 2)
|
||||
for job_host_summary in job.job_host_summaries.all():
|
||||
unicode(job_host_summary) # For test coverage.
|
||||
self.assertFalse(job_host_summary.failed)
|
||||
@ -261,14 +298,7 @@ class RunJobTest(BaseCeleryTest):
|
||||
self.assertEqual(job.status, 'pending')
|
||||
job = Job.objects.get(pk=job.pk)
|
||||
self.check_job_result(job, 'successful')
|
||||
job_events = job.job_events.all()
|
||||
self.assertEqual(job_events.filter(event='playbook_on_start').count(), 1)
|
||||
self.assertEqual(job_events.filter(event='playbook_on_play_start').count(), 1)
|
||||
self.assertEqual(job_events.filter(event='playbook_on_task_start').count(), 2)
|
||||
self.assertEqual(job_events.filter(event='runner_on_skipped').count(), 2)
|
||||
for evt in job_events.filter(event='runner_on_skipped'):
|
||||
self.assertEqual(evt.host, self.host)
|
||||
self.assertEqual(job_events.filter(event='playbook_on_stats').count(), 1)
|
||||
self.check_job_events(job, 'skipped', 1, 2)
|
||||
for job_host_summary in job.job_host_summaries.all():
|
||||
self.assertFalse(job_host_summary.failed)
|
||||
self.assertEqual(job_host_summary.host.last_job_host_summary, job_host_summary)
|
||||
@ -295,13 +325,7 @@ class RunJobTest(BaseCeleryTest):
|
||||
self.assertEqual(job.status, 'pending')
|
||||
job = Job.objects.get(pk=job.pk)
|
||||
self.check_job_result(job, 'failed')
|
||||
job_events = job.job_events.all()
|
||||
self.assertEqual(job_events.filter(event='playbook_on_start').count(), 1)
|
||||
self.assertEqual(job_events.filter(event='playbook_on_play_start').count(), 1)
|
||||
self.assertEqual(job_events.filter(event='playbook_on_task_start').count(), 1)
|
||||
self.assertEqual(job_events.filter(event='runner_on_failed').count(), 1)
|
||||
self.assertEqual(job_events.get(event='runner_on_failed').host, self.host)
|
||||
self.assertEqual(job_events.filter(event='playbook_on_stats').count(), 1)
|
||||
self.check_job_events(job, 'failed', 1, 1)
|
||||
for job_host_summary in job.job_host_summaries.all():
|
||||
self.assertTrue(job_host_summary.failed)
|
||||
self.assertEqual(job_host_summary.host.last_job_host_summary, job_host_summary)
|
||||
@ -330,13 +354,7 @@ class RunJobTest(BaseCeleryTest):
|
||||
# Since we don't actually run the task, the --check should indicate
|
||||
# everything is successful.
|
||||
self.check_job_result(job, 'successful')
|
||||
job_events = job.job_events.all()
|
||||
self.assertEqual(job_events.filter(event='playbook_on_start').count(), 1)
|
||||
self.assertEqual(job_events.filter(event='playbook_on_play_start').count(), 1)
|
||||
self.assertEqual(job_events.filter(event='playbook_on_task_start').count(), 1)
|
||||
self.assertEqual(job_events.filter(event='runner_on_skipped').count(), 1)
|
||||
self.assertEqual(job_events.get(event='runner_on_skipped').host, self.host)
|
||||
self.assertEqual(job_events.filter(event='playbook_on_stats').count(), 1)
|
||||
self.check_job_events(job, 'skipped', 1, 1)
|
||||
for job_host_summary in job.job_host_summaries.all():
|
||||
self.assertFalse(job_host_summary.failed)
|
||||
self.assertEqual(job_host_summary.host.last_job_host_summary, job_host_summary)
|
||||
|
||||
@ -93,14 +93,14 @@ class CallbackModule(object):
|
||||
auth = TokenAuth(self.auth_token)
|
||||
else:
|
||||
auth = None
|
||||
port = parts.port or (443 if parts.scheme == 'https' else 80)
|
||||
url = urlparse.urlunsplit([parts.scheme,
|
||||
'%s:%d' % (parts.hostname, parts.port),
|
||||
'%s:%d' % (parts.hostname, port),
|
||||
parts.path, parts.query, parts.fragment])
|
||||
url_path = '/api/v1/jobs/%d/job_events/' % self.job_id
|
||||
url = urlparse.urljoin(url, url_path)
|
||||
headers = {'content-type': 'application/json'}
|
||||
response = requests.post(url, data=data, headers=headers, auth=auth)
|
||||
print response.content
|
||||
response.raise_for_status()
|
||||
|
||||
def _log_event(self, event, **event_data):
|
||||
|
||||
@ -71,8 +71,9 @@ class InventoryScript(object):
|
||||
auth = TokenAuth(self.auth_token)
|
||||
else:
|
||||
auth = None
|
||||
port = parts.port or (443 if parts.scheme == 'https' else 80)
|
||||
url = urlparse.urlunsplit([parts.scheme,
|
||||
'%s:%d' % (parts.hostname, parts.port),
|
||||
'%s:%d' % (parts.hostname, port),
|
||||
parts.path, parts.query, parts.fragment])
|
||||
url_path = '/api/v1/inventories/%d/script/' % self.inventory_id
|
||||
if self.hostname:
|
||||
@ -80,7 +81,8 @@ class InventoryScript(object):
|
||||
url = urlparse.urljoin(url, url_path)
|
||||
response = requests.get(url, auth=auth)
|
||||
response.raise_for_status()
|
||||
sys.stdout.write(json.dumps(response.json(), indent=self.indent) + '\n')
|
||||
sys.stdout.write(json.dumps(json.loads(response.content),
|
||||
indent=self.indent) + '\n')
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
|
||||
@ -22,13 +22,13 @@ DATABASES = {
|
||||
}
|
||||
}
|
||||
|
||||
# Continue to use SQLite for unit tests instead of PostgreSQL.
|
||||
if 'test' in sys.argv:
|
||||
# Use SQLite for unit tests instead of PostgreSQL.
|
||||
if len(sys.argv) >= 2 and sys.argv[1] == 'test':
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': os.path.join(BASE_DIR, 'awx.sqlite3'),
|
||||
# Test database cannot be :memory: for celery/inventory tests to work.
|
||||
# Test database cannot be :memory: for celery/inventory tests.
|
||||
'TEST_NAME': os.path.join(BASE_DIR, 'awx_test.sqlite3'),
|
||||
}
|
||||
}
|
||||
|
||||
BIN
awx/ui/.DS_Store
vendored
Normal file
BIN
awx/ui/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
awx/ui/static/.DS_Store
vendored
Normal file
BIN
awx/ui/static/.DS_Store
vendored
Normal file
Binary file not shown.
@ -13,7 +13,7 @@
|
||||
|
||||
body {
|
||||
color: #36454F;
|
||||
padding-top: 40px;
|
||||
padding-top: 60px;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
@ -42,6 +42,7 @@
|
||||
background-repeat: repeat-x;
|
||||
border-color: #36454F;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#36454F', endColorstr='#36454F', GradientType=0);
|
||||
padding-right: 15px;
|
||||
}
|
||||
|
||||
.navbar-inverse .nav > li > a {
|
||||
@ -55,10 +56,15 @@
|
||||
|
||||
.navbar .brand {
|
||||
margin-left: 15px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.navbar .brand img {
|
||||
width: 130px;
|
||||
width: 260px;
|
||||
}
|
||||
|
||||
.navbar .nav {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
|
||||
BIN
awx/ui/static/img/logo.png
Normal file
BIN
awx/ui/static/img/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.7 KiB |
@ -175,7 +175,7 @@ function InventoriesAdd ($scope, $rootScope, $compile, $location, $log, $routePa
|
||||
var form = InventoryForm;
|
||||
var generator = GenerateForm;
|
||||
var scope = generator.inject(form, {mode: 'add', related: false});
|
||||
scope.parseType = 'json';
|
||||
scope.parseType = 'yaml';
|
||||
|
||||
generator.reset();
|
||||
LoadBreadCrumbs();
|
||||
@ -239,7 +239,7 @@ function InventoriesAdd ($scope, $rootScope, $compile, $location, $log, $routePa
|
||||
});
|
||||
}
|
||||
catch(err) {
|
||||
Alert("Error", "Error parsing inventory variables. Parser returned " + err);
|
||||
Alert("Error", "Error parsing inventory variables. Parser returned: " + err);
|
||||
}
|
||||
|
||||
};
|
||||
@ -275,7 +275,7 @@ function InventoriesEdit ($scope, $rootScope, $compile, $location, $log, $routeP
|
||||
|
||||
ParseTypeChange(scope);
|
||||
|
||||
scope.parseType = 'json';
|
||||
scope.parseType = 'yaml';
|
||||
scope['inventory_id'] = id;
|
||||
|
||||
// Retrieve each related set and any lookups
|
||||
@ -300,10 +300,10 @@ function InventoriesEdit ($scope, $rootScope, $compile, $location, $log, $routeP
|
||||
Rest.get()
|
||||
.success( function(data, status, headers, config) {
|
||||
if ($.isEmptyObject(data)) {
|
||||
scope.variables = "\{\}";
|
||||
scope.variables = "---";
|
||||
}
|
||||
else {
|
||||
scope.variables = JSON.stringify(data, null, " ");
|
||||
scope.variables = jsyaml.safeDump(data);
|
||||
}
|
||||
})
|
||||
.error( function(data, status, headers, config) {
|
||||
@ -313,7 +313,7 @@ function InventoriesEdit ($scope, $rootScope, $compile, $location, $log, $routeP
|
||||
});
|
||||
}
|
||||
else {
|
||||
scope.variables = "\{\}";
|
||||
scope.variables = "---";
|
||||
}
|
||||
});
|
||||
|
||||
@ -371,7 +371,7 @@ function InventoriesEdit ($scope, $rootScope, $compile, $location, $log, $routeP
|
||||
});
|
||||
}
|
||||
catch(err) {
|
||||
Alert("Error", "Error parsing inventory variables. Parser returned " + err);
|
||||
Alert("Error", "Error parsing inventory variables. Parser returned: " + err);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@ -159,7 +159,7 @@ JobTemplatesList.$inject = [ '$scope', '$rootScope', '$location', '$log', '$rout
|
||||
|
||||
function JobTemplatesAdd ($scope, $rootScope, $compile, $location, $log, $routeParams, JobTemplateForm,
|
||||
GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope,
|
||||
GetBasePath, InventoryList, CredentialList, ProjectList, LookUpInit, md5Setup)
|
||||
GetBasePath, InventoryList, CredentialList, ProjectList, LookUpInit, md5Setup, ParseTypeChange)
|
||||
{
|
||||
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
|
||||
//scope.
|
||||
@ -170,6 +170,9 @@ function JobTemplatesAdd ($scope, $rootScope, $compile, $location, $log, $routeP
|
||||
var generator = GenerateForm;
|
||||
var scope = generator.inject(form, {mode: 'add', related: false});
|
||||
var master = {};
|
||||
|
||||
scope.parseType = 'yaml';
|
||||
ParseTypeChange(scope);
|
||||
|
||||
scope.job_type_options = [{ value: 'run', label: 'Run' }, { value: 'check', label: 'Check' }];
|
||||
scope.verbosity_options = [
|
||||
@ -243,25 +246,43 @@ function JobTemplatesAdd ($scope, $rootScope, $compile, $location, $log, $routeP
|
||||
|
||||
// Save
|
||||
scope.formSave = function() {
|
||||
Rest.setUrl(defaultUrl);
|
||||
var data = {}
|
||||
for (var fld in form.fields) {
|
||||
if (form.fields[fld].type == 'select' && fld != 'playbook') {
|
||||
data[fld] = scope[fld].value;
|
||||
try {
|
||||
// Make sure we have valid variable data
|
||||
if (scope.parseType == 'json') {
|
||||
var myjson = JSON.parse(scope.variables); //make sure JSON parses
|
||||
var json_data = scope.variables;
|
||||
}
|
||||
else {
|
||||
data[fld] = scope[fld];
|
||||
}
|
||||
var json_data = jsyaml.load(scope.variables); //parse yaml
|
||||
}
|
||||
|
||||
for (var fld in form.fields) {
|
||||
if (form.fields[fld].type == 'select' && fld != 'playbook') {
|
||||
data[fld] = scope[fld].value;
|
||||
}
|
||||
else {
|
||||
if (fld != 'variables') {
|
||||
data[fld] = scope[fld];
|
||||
}
|
||||
}
|
||||
}
|
||||
data.extra_vars = json_data;
|
||||
Rest.setUrl(defaultUrl);
|
||||
Rest.post(data)
|
||||
.success( function(data, status, headers, config) {
|
||||
var base = $location.path().replace(/^\//,'').split('/')[0];
|
||||
(base == 'job_templates') ? ReturnToCaller() : ReturnToCaller(1);
|
||||
})
|
||||
.error( function(data, status, headers, config) {
|
||||
ProcessErrors(scope, data, status, form,
|
||||
{ hdr: 'Error!', msg: 'Failed to add new job template. POST returned status: ' + status });
|
||||
});
|
||||
|
||||
}
|
||||
catch(err) {
|
||||
Alert("Error", "Error parsing extra variables. Parser returned: " + err);
|
||||
}
|
||||
Rest.post(data)
|
||||
.success( function(data, status, headers, config) {
|
||||
var base = $location.path().replace(/^\//,'').split('/')[0];
|
||||
(base == 'job_templates') ? ReturnToCaller() : ReturnToCaller(1);
|
||||
})
|
||||
.error( function(data, status, headers, config) {
|
||||
ProcessErrors(scope, data, status, form,
|
||||
{ hdr: 'Error!', msg: 'Failed to add new project. POST returned status: ' + status });
|
||||
});
|
||||
};
|
||||
|
||||
// Reset
|
||||
@ -277,13 +298,13 @@ function JobTemplatesAdd ($scope, $rootScope, $compile, $location, $log, $routeP
|
||||
|
||||
JobTemplatesAdd.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'JobTemplateForm',
|
||||
'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope',
|
||||
'GetBasePath', 'InventoryList', 'CredentialList', 'ProjectList', 'LookUpInit', 'md5Setup' ];
|
||||
'GetBasePath', 'InventoryList', 'CredentialList', 'ProjectList', 'LookUpInit', 'md5Setup', 'ParseTypeChange' ];
|
||||
|
||||
|
||||
function JobTemplatesEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, JobTemplateForm,
|
||||
GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit,
|
||||
RelatedPaginateInit, ReturnToCaller, ClearScope, InventoryList, CredentialList,
|
||||
ProjectList, LookUpInit, PromptPasswords, GetBasePath, md5Setup)
|
||||
ProjectList, LookUpInit, PromptPasswords, GetBasePath, md5Setup, ParseTypeChange)
|
||||
{
|
||||
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
|
||||
//scope.
|
||||
@ -293,6 +314,9 @@ function JobTemplatesEdit ($scope, $rootScope, $compile, $location, $log, $route
|
||||
var form = JobTemplateForm;
|
||||
var scope = generator.inject(form, {mode: 'edit', related: true});
|
||||
|
||||
scope.parseType = 'yaml';
|
||||
ParseTypeChange(scope);
|
||||
|
||||
// Our job type options
|
||||
scope.job_type_options = [{ value: 'run', label: 'Run' }, { value: 'check', label: 'Check' }];
|
||||
scope.verbosity_options = [
|
||||
@ -365,7 +389,7 @@ function JobTemplatesEdit ($scope, $rootScope, $compile, $location, $log, $route
|
||||
.success( function(data, status, headers, config) {
|
||||
LoadBreadCrumbs({ path: '/job_templates/' + id, title: data.name });
|
||||
for (var fld in form.fields) {
|
||||
if (data[fld] !== null && data[fld] !== undefined) {
|
||||
if (fld != 'variables' && data[fld] !== null && data[fld] !== undefined) {
|
||||
if (form.fields[fld].type == 'select') {
|
||||
if (scope[fld + '_options'] && scope[fld + '_options'].length > 0) {
|
||||
for (var i=0; i < scope[fld + '_options'].length; i++) {
|
||||
@ -383,6 +407,16 @@ function JobTemplatesEdit ($scope, $rootScope, $compile, $location, $log, $route
|
||||
}
|
||||
master[fld] = scope[fld];
|
||||
}
|
||||
if (fld == 'variables') {
|
||||
// Parse extra_vars, converting to YAML.
|
||||
if ($.isEmptyObject(data.extra_vars) || data.extra_vars == "\{\}") {
|
||||
scope.variables = "---";
|
||||
}
|
||||
else {
|
||||
scope.variables = jsyaml.safeDump(JSON.parse(data.extra_vars));
|
||||
}
|
||||
master.variables = scope.variables;
|
||||
}
|
||||
if (form.fields[fld].type == 'lookup' && data.summary_fields[form.fields[fld].sourceModel]) {
|
||||
scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] =
|
||||
data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField];
|
||||
@ -435,24 +469,42 @@ function JobTemplatesEdit ($scope, $rootScope, $compile, $location, $log, $route
|
||||
// Save changes to the parent
|
||||
scope.formSave = function() {
|
||||
var data = {}
|
||||
for (var fld in form.fields) {
|
||||
if (form.fields[fld].type == 'select' && fld != 'playbook') {
|
||||
data[fld] = scope[fld].value;
|
||||
try {
|
||||
// Make sure we have valid variable data
|
||||
if (scope.parseType == 'json') {
|
||||
var myjson = JSON.parse(scope.variables); //make sure JSON parses
|
||||
var json_data = scope.variables;
|
||||
}
|
||||
else {
|
||||
data[fld] = scope[fld];
|
||||
}
|
||||
}
|
||||
Rest.setUrl(defaultUrl + $routeParams.id + '/');
|
||||
Rest.put(data)
|
||||
.success( function(data, status, headers, config) {
|
||||
var base = $location.path().replace(/^\//,'').split('/')[0];
|
||||
(base == 'job_templates') ? ReturnToCaller() : ReturnToCaller(1);
|
||||
})
|
||||
.error( function(data, status, headers, config) {
|
||||
ProcessErrors(scope, data, status, form,
|
||||
{ hdr: 'Error!', msg: 'Failed to update team: ' + $routeParams.id + '. PUT status: ' + status });
|
||||
});
|
||||
var json_data = jsyaml.load(scope.variables); //parse yaml
|
||||
}
|
||||
|
||||
for (var fld in form.fields) {
|
||||
if (form.fields[fld].type == 'select' && fld != 'playbook') {
|
||||
data[fld] = scope[fld].value;
|
||||
}
|
||||
else {
|
||||
if (fld != 'variables') {
|
||||
data[fld] = scope[fld];
|
||||
}
|
||||
}
|
||||
}
|
||||
data.extra_vars = json_data;
|
||||
Rest.setUrl(defaultUrl + id + '/');
|
||||
Rest.put(data)
|
||||
.success( function(data, status, headers, config) {
|
||||
var base = $location.path().replace(/^\//,'').split('/')[0];
|
||||
(base == 'job_templates') ? ReturnToCaller() : ReturnToCaller(1);
|
||||
})
|
||||
.error( function(data, status, headers, config) {
|
||||
ProcessErrors(scope, data, status, form,
|
||||
{ hdr: 'Error!', msg: 'Failed to update job template. PUT returned status: ' + status });
|
||||
});
|
||||
|
||||
}
|
||||
catch(err) {
|
||||
Alert("Error", "Error parsing extra variables. Parser returned: " + err);
|
||||
}
|
||||
};
|
||||
|
||||
// Cancel
|
||||
@ -461,6 +513,7 @@ function JobTemplatesEdit ($scope, $rootScope, $compile, $location, $log, $route
|
||||
for (var fld in master) {
|
||||
scope[fld] = master[fld];
|
||||
}
|
||||
scope.parseType = 'yaml';
|
||||
$('#forks-slider').slider("option", "value", scope.forks);
|
||||
};
|
||||
|
||||
@ -506,5 +559,5 @@ function JobTemplatesEdit ($scope, $rootScope, $compile, $location, $log, $route
|
||||
JobTemplatesEdit.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'JobTemplateForm',
|
||||
'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit',
|
||||
'RelatedPaginateInit', 'ReturnToCaller', 'ClearScope', 'InventoryList', 'CredentialList',
|
||||
'ProjectList', 'LookUpInit', 'PromptPasswords', 'GetBasePath', 'md5Setup'
|
||||
'ProjectList', 'LookUpInit', 'PromptPasswords', 'GetBasePath', 'md5Setup', 'ParseTypeChange'
|
||||
];
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
|
||||
function PermissionsList ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, PermissionList,
|
||||
GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller,
|
||||
ClearScope, ProcessErrors, GetBasePath)
|
||||
ClearScope, ProcessErrors, GetBasePath, CheckAccess)
|
||||
{
|
||||
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
|
||||
//scope.
|
||||
@ -22,13 +22,13 @@ function PermissionsList ($scope, $rootScope, $location, $log, $routeParams, Res
|
||||
LoadBreadCrumbs();
|
||||
|
||||
scope.addPermission = function() {
|
||||
if (checkAccess()) {
|
||||
if (CheckAccess()) {
|
||||
$location.path($location.path() + '/add');
|
||||
}
|
||||
}
|
||||
|
||||
scope.editPermission = function(id) {
|
||||
if (checkAccess()) {
|
||||
if (CheckAccess()) {
|
||||
$location.path($location.path() + '/' + id);
|
||||
}
|
||||
}
|
||||
@ -60,7 +60,7 @@ function PermissionsList ($scope, $rootScope, $location, $log, $routeParams, Res
|
||||
|
||||
PermissionsList.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'PermissionList',
|
||||
'GenerateList', 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller',
|
||||
'ClearScope', 'ProcessErrors', 'GetBasePath'
|
||||
'ClearScope', 'ProcessErrors', 'GetBasePath', 'CheckAccess'
|
||||
];
|
||||
|
||||
|
||||
|
||||
@ -36,7 +36,7 @@ angular.module('GroupFormDefinition', [])
|
||||
editRequird: false,
|
||||
rows: 10,
|
||||
"class": 'modal-input-xlarge',
|
||||
"default": "\{\}",
|
||||
"default": "---",
|
||||
dataTitle: 'Group Variables',
|
||||
dataPlacement: 'right',
|
||||
awPopOver: "<p>Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.</p>" +
|
||||
|
||||
@ -41,7 +41,7 @@ angular.module('HostFormDefinition', [])
|
||||
editRequird: false,
|
||||
rows: 10,
|
||||
"class": "modal-input-xlarge",
|
||||
"default": "\{\}",
|
||||
"default": "---",
|
||||
awPopOver: "<p>Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.</p>" +
|
||||
'<p>View JSON examples at <a href="http://www.json.org" target="_blank">www.json.org</a></p>' +
|
||||
'<p>View YAML examples at <a href="http://www.ansibleworks.com/docs/YAMLSyntax.html" target="_blank">ansibleworks.com</a></p>',
|
||||
|
||||
@ -63,7 +63,7 @@ angular.module('InventoryFormDefinition', [])
|
||||
editRequird: false,
|
||||
rows: 10,
|
||||
"class": "modal-input-xlarge",
|
||||
"default": "\{\}",
|
||||
"default": "---",
|
||||
awPopOver: "<p>Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.</p>" +
|
||||
'<p>View JSON examples at <a href="http://www.json.org" target="_blank">www.json.org</a></p>' +
|
||||
'<p>View YAML examples at <a href="http://www.ansibleworks.com/docs/YAMLSyntax.html" target="_blank">ansibleworks.com</a></p>',
|
||||
|
||||
@ -127,17 +127,17 @@ angular.module('JobTemplateFormDefinition', [])
|
||||
dataTitle: 'Verbosity',
|
||||
dataPlacement: 'left'
|
||||
},
|
||||
extra_vars: {
|
||||
variables: {
|
||||
label: 'Extra Variables',
|
||||
type: 'textarea',
|
||||
rows: 6,
|
||||
"class": 'span12',
|
||||
addRequired: false,
|
||||
editRequired: false,
|
||||
"default": "\{\}",
|
||||
"default": "---",
|
||||
column: 2,
|
||||
awPopOver: "<p>Pass extra command line variables to the playbook. This is the -e or --extra-vars command line parameter " +
|
||||
"for ansible-playbook. Provide key=value pairs or JSON. <p><a href=\"http://www.ansibleworks.com/docs/playbooks2.html" +
|
||||
"for ansible-playbook. Provide key/value pairs using either YAML or JSON. <p><a href=\"http://www.ansibleworks.com/docs/playbooks2.html" +
|
||||
"#passing-variables-on-the-command-line\" target=\"_blank\">Click here to view documentation and examples.</a></p>",
|
||||
dataTitle: 'Extra Variables',
|
||||
dataPlacement: 'left'
|
||||
|
||||
@ -126,17 +126,20 @@ angular.module('TeamFormDefinition', [])
|
||||
label: 'Name',
|
||||
ngClick: "edit('permissions', \{\{ permission.id \}\}, '\{\{ permission.name \}\}')"
|
||||
},
|
||||
inventory: {
|
||||
label: 'Inventory',
|
||||
sourceModel: 'inventory',
|
||||
sourceField: 'name',
|
||||
ngBind: 'permission.summary_fields.inventory.name',
|
||||
},
|
||||
project: {
|
||||
label: 'Project',
|
||||
sourceModel: 'project',
|
||||
sourceField: 'name',
|
||||
ngBind: 'permission.summary_fields.project.name',
|
||||
},
|
||||
inventory: {
|
||||
label: 'Inventory',
|
||||
sourceModel: 'inventory',
|
||||
sourceField: 'name',
|
||||
ngBind: 'permission.summary_fields.inventory.name',
|
||||
permission_type: {
|
||||
label: 'Permission'
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -163,18 +163,22 @@ angular.module('UserFormDefinition', [])
|
||||
label: 'Name',
|
||||
ngClick: "edit('permissions', \{\{ permission.id \}\}, '\{\{ permission.name \}\}')"
|
||||
},
|
||||
inventory: {
|
||||
label: 'Inventory',
|
||||
sourceModel: 'inventory',
|
||||
sourceField: 'name',
|
||||
ngBind: 'permission.summary_fields.inventory.name',
|
||||
},
|
||||
project: {
|
||||
label: 'Project',
|
||||
sourceModel: 'project',
|
||||
sourceField: 'name',
|
||||
ngBind: 'permission.summary_fields.project.name',
|
||||
},
|
||||
inventory: {
|
||||
label: 'Inventory',
|
||||
sourceModel: 'inventory',
|
||||
sourceField: 'name',
|
||||
ngBind: 'permission.summary_fields.inventory.name',
|
||||
permission_type: {
|
||||
label: 'Permission'
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
fieldActions: {
|
||||
|
||||
@ -175,7 +175,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
|
||||
scope.formModalActionLabel = 'Save';
|
||||
scope.formModalHeader = 'Create Group';
|
||||
scope.formModalCancelShow = true;
|
||||
scope.parseType = 'json';
|
||||
scope.parseType = 'yaml';
|
||||
ParseTypeChange(scope);
|
||||
|
||||
$('#form-modal .btn-none').removeClass('btn-none').addClass('btn-success');
|
||||
@ -237,7 +237,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
|
||||
});
|
||||
}
|
||||
catch(err) {
|
||||
Alert("Error", "Error parsing group variables. Expecting valid JSON. Parser returned " + err);
|
||||
Alert("Error", "Error parsing group variables. Parser returned: " + err);
|
||||
}
|
||||
}
|
||||
|
||||
@ -270,7 +270,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
|
||||
scope.formModalActionLabel = 'Save';
|
||||
scope.formModalHeader = 'Edit Group';
|
||||
scope.formModalCancelShow = true;
|
||||
scope.parseType = 'json';
|
||||
scope.parseType = 'yaml';
|
||||
ParseTypeChange(scope);
|
||||
|
||||
$('#form-modal .btn-none').removeClass('btn-none').addClass('btn-success');
|
||||
@ -288,10 +288,10 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
|
||||
Rest.get()
|
||||
.success( function(data, status, headers, config) {
|
||||
if ($.isEmptyObject(data)) {
|
||||
scope.variables = "\{\}";
|
||||
scope.variables = "---";
|
||||
}
|
||||
else {
|
||||
scope.variables = JSON.stringify(data, null, " ");
|
||||
scope.variables = jsyaml.safeDump(data);
|
||||
}
|
||||
})
|
||||
.error( function(data, status, headers, config) {
|
||||
@ -301,8 +301,9 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
|
||||
});
|
||||
}
|
||||
else {
|
||||
scope.variables = "\{\}";
|
||||
scope.variables = "---";
|
||||
}
|
||||
master.variables = scope.variables;
|
||||
});
|
||||
|
||||
// Retrieve detail record and prepopulate the form
|
||||
@ -378,7 +379,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
|
||||
});
|
||||
}
|
||||
catch(err) {
|
||||
Alert("Error", "Error parsing group variables. Expecting valid JSON. Parser returned " + err);
|
||||
Alert("Error", "Error parsing group variables. Parser returned: " + err);
|
||||
}
|
||||
};
|
||||
|
||||
@ -388,6 +389,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
|
||||
for (var fld in master) {
|
||||
scope[fld] = master[fld];
|
||||
}
|
||||
scope.parseType = 'yaml';
|
||||
}
|
||||
}
|
||||
}])
|
||||
|
||||
@ -165,7 +165,7 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H
|
||||
scope.formModalActionLabel = 'Save';
|
||||
scope.formModalHeader = 'Create Host';
|
||||
scope.formModalCancelShow = true;
|
||||
scope.parseType = 'json';
|
||||
scope.parseType = 'yaml';
|
||||
ParseTypeChange(scope);
|
||||
|
||||
$('#form-modal .btn-none').removeClass('btn-none').addClass('btn-success');
|
||||
@ -223,7 +223,7 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H
|
||||
});
|
||||
}
|
||||
catch(err) {
|
||||
Alert("Error", "Error parsing host variables. Parser returned " + err);
|
||||
Alert("Error", "Error parsing host variables. Parser returned: " + err);
|
||||
}
|
||||
}
|
||||
|
||||
@ -258,7 +258,7 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H
|
||||
scope.formModalActionLabel = 'Save';
|
||||
scope.formModalHeader = 'Edit Host';
|
||||
scope.formModalCancelShow = true;
|
||||
scope.parseType = 'json';
|
||||
scope.parseType = 'yaml';
|
||||
ParseTypeChange(scope);
|
||||
|
||||
$('#form-modal .btn-none').removeClass('btn-none').addClass('btn-success');
|
||||
@ -275,10 +275,10 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H
|
||||
Rest.get()
|
||||
.success( function(data, status, headers, config) {
|
||||
if ($.isEmptyObject(data)) {
|
||||
scope.variables = "\{\}";
|
||||
scope.variables = "---";
|
||||
}
|
||||
else {
|
||||
scope.variables = JSON.stringify(data, null, " ");
|
||||
scope.variables = jsyaml.safeDump(data);
|
||||
}
|
||||
})
|
||||
.error( function(data, status, headers, config) {
|
||||
@ -288,8 +288,9 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H
|
||||
});
|
||||
}
|
||||
else {
|
||||
scope.variables = "\{\}";
|
||||
scope.variables = "---";
|
||||
}
|
||||
master.variables = scope.variables;
|
||||
});
|
||||
|
||||
// Retrieve detail record and prepopulate the form
|
||||
@ -363,7 +364,7 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H
|
||||
});
|
||||
}
|
||||
catch(err) {
|
||||
Alert("Error", "Error parsing group variables. Expecting valid JSON. Parser returned " + err);
|
||||
Alert("Error", "Error parsing group variables. Parser returned: " + err);
|
||||
}
|
||||
};
|
||||
|
||||
@ -373,6 +374,7 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H
|
||||
for (var fld in master) {
|
||||
scope[fld] = master[fld];
|
||||
}
|
||||
scope.parseType = 'yaml';
|
||||
}
|
||||
}
|
||||
}])
|
||||
|
||||
@ -60,7 +60,7 @@ angular.module('RelatedSearchHelper', ['RestServices', 'Utilities','RefreshRelat
|
||||
|
||||
for (var related in form.related) {
|
||||
if ( form.related[related].iterator == iterator ) {
|
||||
var f = form.related[set].fields[fld];
|
||||
var f = form.related[related].fields[fld];
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,15 +71,15 @@ angular.module('RelatedSearchHelper', ['RestServices', 'Utilities','RefreshRelat
|
||||
scope[iterator + 'HideSearchType'] = false;
|
||||
scope[iterator + 'InputHide'] = false;
|
||||
|
||||
if (f.searchType && f.searchType == 'gtzero') {
|
||||
if (f.searchType !== undefined && f.searchType == 'gtzero') {
|
||||
scope[iterator + "InputHide"] = true;
|
||||
}
|
||||
if (f.searchType && (f.searchType == 'boolean'
|
||||
if (f.searchType !== undefined && (f.searchType == 'boolean'
|
||||
|| f.searchType == 'select')) {
|
||||
scope[iterator + 'SelectShow'] = true;
|
||||
scope[iterator + 'SearchSelectOpts'] = f.searchOptions;
|
||||
}
|
||||
if (f.searchType && f.searchType == 'int') {
|
||||
if (f.searchType !== undefined && f.searchType == 'int') {
|
||||
scope[iterator + 'HideSearchType'] = true;
|
||||
}
|
||||
|
||||
|
||||
@ -37,7 +37,7 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
|
||||
else {
|
||||
sort_order = (list.fields[fld].desc) ? '-' + fld : fld;
|
||||
}
|
||||
if (list.fields[fld].notSearchable == undefined || list.fields[fld].notSearchable == false) {
|
||||
if (list.fields[fld].searchable == undefined || list.fields[fld].searchable == true) {
|
||||
scope[iterator + 'SearchField'] = fld;
|
||||
scope[iterator + 'SearchFieldLabel'] = list.fields[fld].label;
|
||||
}
|
||||
@ -46,9 +46,9 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
|
||||
}
|
||||
|
||||
if (!scope[iterator + 'SearchField']) {
|
||||
// A field marked as key may also be notSearchable
|
||||
// A field marked as key may not be 'searchable'
|
||||
for (fld in list.fields) {
|
||||
if (list.fields[fld].notSearchable == undefined || list.fields[fld].notSearchable == false) {
|
||||
if (list.fields[fld].searchable == undefined || list.fields[fld].searchable == true) {
|
||||
scope[iterator + 'SearchField'] = fld;
|
||||
scope[iterator + 'SearchFieldLabel'] = list.fields[fld].label;
|
||||
break;
|
||||
|
||||
@ -19,10 +19,10 @@ angular.module('JobEventsListDefinition', [])
|
||||
|
||||
fields: {
|
||||
created: {
|
||||
label: 'Creation Date',
|
||||
label: 'Date',
|
||||
key: true,
|
||||
nosort: true,
|
||||
notSearchable: true,
|
||||
searchable: false,
|
||||
ngClick: "viewJobEvent(\{\{ jobevent.id \}\})",
|
||||
},
|
||||
event_display: {
|
||||
@ -30,7 +30,7 @@ angular.module('JobEventsListDefinition', [])
|
||||
hasChildren: true,
|
||||
ngClick: "viewJobEvent(\{\{ jobevent.id \}\})",
|
||||
nosort: true,
|
||||
notSearchable: true
|
||||
searchable: false
|
||||
},
|
||||
host: {
|
||||
label: 'Host',
|
||||
@ -47,7 +47,8 @@ angular.module('JobEventsListDefinition', [])
|
||||
searchField: 'failed',
|
||||
searchType: 'boolean',
|
||||
searchOptions: [{ name: "success", value: 0 }, { name: "error", value: 1 }],
|
||||
nosort: true
|
||||
nosort: true,
|
||||
searchable: false,
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -27,11 +27,11 @@ angular.module('JobHostDefinition', [])
|
||||
},
|
||||
ok: {
|
||||
label: 'Success',
|
||||
notSearchable: true
|
||||
searchable: false
|
||||
},
|
||||
changed: {
|
||||
label: 'Changed',
|
||||
notSearchable: true
|
||||
searchable: false
|
||||
},
|
||||
failures: {
|
||||
label: 'Failure',
|
||||
@ -39,11 +39,11 @@ angular.module('JobHostDefinition', [])
|
||||
},
|
||||
dark: {
|
||||
label: 'Unreachable',
|
||||
notSearchable: true
|
||||
searchable: false
|
||||
},
|
||||
skipped: {
|
||||
label: 'Skipped',
|
||||
notSearchable: true
|
||||
searchable: false
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -34,7 +34,7 @@ angular.module('JobsListDefinition', [])
|
||||
link: true
|
||||
},
|
||||
created: {
|
||||
label: 'Creation Date',
|
||||
label: 'Date',
|
||||
link: true
|
||||
},
|
||||
status: {
|
||||
|
||||
@ -24,8 +24,11 @@ angular.module('PermissionListDefinition', [])
|
||||
label: 'Name',
|
||||
ngClick: 'editPermission(\{\{ permission.id \}\})'
|
||||
},
|
||||
description: {
|
||||
label: 'Description'
|
||||
inventory: {
|
||||
label: 'Inventory',
|
||||
sourceModel: 'inventory',
|
||||
sourceField: 'name',
|
||||
ngBind: 'permission.summary_fields.inventory.name'
|
||||
},
|
||||
project: {
|
||||
label: 'Project',
|
||||
@ -33,12 +36,9 @@ angular.module('PermissionListDefinition', [])
|
||||
sourceField: 'name',
|
||||
ngBind: 'permission.summary_fields.project.name'
|
||||
},
|
||||
inventory: {
|
||||
label: 'Inventory',
|
||||
sourceModel: 'inventory',
|
||||
sourceField: 'name',
|
||||
ngBind: 'permission.summary_fields.inventory.name'
|
||||
},
|
||||
permission_type: {
|
||||
label: 'Permission'
|
||||
}
|
||||
},
|
||||
|
||||
actions: {
|
||||
|
||||
@ -233,8 +233,8 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies'])
|
||||
if (field.genMD5) {
|
||||
html += " \n<button class=\"btn\" ng-click=\"genMD5('" + fld + "')\" " +
|
||||
"aw-tool-tip=\"Generate " + field.label + "\" data-placement=\"top\" id=\"" + fld + "-gen-btn\"><i class=\"icon-repeat\"></i></button>\n";
|
||||
html += " \n<button style=\"margin-left: 10px;\" class=\"btn\" ng-click=\"selectAll('" + fld + "')\" " +
|
||||
"aw-tool-tip=\"Select " + field.label + " for copy\" data-placement=\"top\" id=\"" + fld + "-copy-btn\"><i class=\"icon-copy\"></i></button>\n";
|
||||
/*html += " \n<button style=\"margin-left: 10px;\" class=\"btn\" ng-click=\"selectAll('" + fld + "')\" " +
|
||||
"aw-tool-tip=\"Select " + field.label + " for copy\" data-placement=\"top\" id=\"" + fld + "-copy-btn\"><i class=\"icon-copy\"></i></button>\n";*/
|
||||
html += "</div>\n";
|
||||
}
|
||||
if (field.ask) {
|
||||
@ -278,10 +278,14 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies'])
|
||||
}
|
||||
html += field.label + '</label>' + "\n";
|
||||
html += "<div class=\"controls\">\n";
|
||||
if (fld == "variables") {
|
||||
html += "<div class=\"parse-selection\">Parse as: <label class=\"radio inline\"><input type=\"radio\" ng-model=\"parseType\" value=\"json\"> JSON</label>\n";
|
||||
html += "<label class=\"radio inline\"><input type=\"radio\" ng-model=\"parseType\" value=\"yaml\"> YAML</label></div>\n";
|
||||
|
||||
// Variable editing
|
||||
if (fld == "variables" || fld == "extra_vars") {
|
||||
html += "<div class=\"parse-selection\">Parse as: " +
|
||||
"<label class=\"radio inline\"><input type=\"radio\" ng-model=\"parseType\" value=\"yaml\"> YAML</label>\n" +
|
||||
"<label class=\"radio inline\"><input type=\"radio\" ng-model=\"parseType\" value=\"json\"> JSON</label></div>\n";
|
||||
}
|
||||
|
||||
html += "<textarea ";
|
||||
html += (field.rows) ? this.attr(field, 'rows') : "";
|
||||
html += "ng-model=\"" + fld + '" ';
|
||||
|
||||
@ -177,7 +177,7 @@ angular.module('GeneratorHelpers', ['GeneratorHelpers'])
|
||||
html += "<ul class=\"dropdown-menu\" id=\"" + iterator + "SearchDropdown\">\n";
|
||||
|
||||
for ( var fld in form.fields) {
|
||||
if (form.fields[fld].notSearchable == undefined || form.fields[fld].notSearchable == false) {
|
||||
if (form.fields[fld].searchable == undefined || form.fields[fld].searchable == true) {
|
||||
html += "<li><a href=\"\" ng-click=\"setSearchField('" + iterator + "','";
|
||||
html += fld + "','" + form.fields[fld].label + "')\">"
|
||||
+ form.fields[fld].label + "</a></li>\n";
|
||||
|
||||
@ -93,7 +93,7 @@
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<a class="brand" href="#/"><img class="logo" src="{{ STATIC_URL }}img/ansibleworks-logo.png" /></a>
|
||||
<a class="brand" href="#/"><img class="logo" src="{{ STATIC_URL }}img/logo.png" /></a>
|
||||
<ul class="nav pull-right">
|
||||
<li ng-show="current_user.username != null && current_user.username != undefined">
|
||||
<a href="" ng-click="viewCurrentUser()" ng-bind="'Hello! ' + current_user.username"></a></li>
|
||||
|
||||
@ -13,6 +13,17 @@ DATABASES = {
|
||||
}
|
||||
}
|
||||
|
||||
# Use SQLite for unit tests instead of PostgreSQL.
|
||||
if len(sys.argv) >= 2 and sys.argv[1] == 'test':
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': 'var/lib/awx/awx.sqlite3',
|
||||
# Test database cannot be :memory: for celery/inventory tests.
|
||||
'TEST_NAME': '/var/lib/awx/awx_test.sqlite3',
|
||||
}
|
||||
}
|
||||
|
||||
STATIC_ROOT = '/var/lib/awx/public/static'
|
||||
|
||||
PROJECTS_ROOT = '/var/lib/awx/projects'
|
||||
|
||||
@ -13,6 +13,17 @@ DATABASES = {
|
||||
}
|
||||
}
|
||||
|
||||
# Use SQLite for unit tests instead of PostgreSQL.
|
||||
if len(sys.argv) >= 2 and sys.argv[1] == 'test':
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': 'var/lib/awx/awx.sqlite3',
|
||||
# Test database cannot be :memory: for celery/inventory tests.
|
||||
'TEST_NAME': '/var/lib/awx/awx_test.sqlite3',
|
||||
}
|
||||
}
|
||||
|
||||
STATIC_ROOT = '/var/lib/awx/public/static'
|
||||
|
||||
PROJECTS_ROOT = '/var/lib/awx/projects'
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
# PIP requirements for AWX development/build environment (using only local
|
||||
packages). Install using "pip --no-index -r dev_local.txt".
|
||||
# packages). Install using "pip --no-index -r dev_local.txt".
|
||||
|
||||
distribute-0.6.45.tar.gz
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user