on host callback, upate dynamic inv only once

* During a job template launch via the host callback launch feature,
when the host launching the job template is not found; we try to launch
associated dyn inv updates to pick up the host. Then the inv is searched
again for the host. If the host is found, then the jt is launched. This
fix carries forward the feature that prevents the dyn inv update with
cache timeout of 0 from being re-launched with the new task manager.
This commit is contained in:
Chris Meyers 2016-11-02 15:45:57 -05:00
parent 549274f97b
commit adcf0af2a0
3 changed files with 36 additions and 10 deletions

View File

@ -230,7 +230,12 @@ class TaskManager():
dependencies.append(project_task)
# Inventory created 2 seconds behind job
inventory_sources_already_updated = task.get_inventory_sources_already_updated()
for inventory_source_task in self.graph.get_inventory_sources(task['inventory_id']):
if inventory_source_task['id'] in inventory_sources_already_updated:
print("Inventory already updated")
continue
if self.graph.should_update_related_inventory_source(task, inventory_source_task['id']):
inventory_task = self.create_inventory_update(task, inventory_source_task)
dependencies.append(inventory_task)

View File

@ -1,5 +1,9 @@
# Python
import json
# AWX
from awx.main.utils import decrypt_field_value
from awx.main.models import (
Job,
ProjectUpdate,
@ -61,7 +65,7 @@ class JobDict(PartialModelDict):
'id', 'status', 'job_template_id', 'inventory_id', 'project_id',
'launch_type', 'limit', 'allow_simultaneous', 'created',
'job_type', 'celery_task_id', 'project__scm_update_on_launch',
'forks',
'forks', 'start_args',
)
model = Job
@ -71,6 +75,14 @@ class JobDict(PartialModelDict):
def task_impact(self):
return (5 if self.data['forks'] == 0 else self.data['forks']) * 10
def get_inventory_sources_already_updated(self):
try:
start_args = json.loads(decrypt_field_value(self.data['id'], 'start_args', self.data['start_args']))
except Exception:
return []
start_args = start_args or {}
return start_args.get('inventory_sources_already_updated', [])
class ProjectUpdateDict(PartialModelDict):
FIELDS = (
'id', 'status', 'project_id', 'created', 'celery_task_id',

View File

@ -155,17 +155,20 @@ def get_awx_version():
return __version__
def get_encryption_key(instance, field_name):
def get_encryption_key_for_pk(pk, field_name):
'''
Generate key for encrypted password based on instance pk and field name.
'''
from django.conf import settings
h = hashlib.sha1()
h.update(settings.SECRET_KEY)
h.update(str(instance.pk))
h.update(str(pk))
h.update(field_name)
return h.digest()[:16]
def get_encryption_key(instance, field_name):
return get_encryption_key_for_pk(instance.pk, field_name)
def encrypt_field(instance, field_name, ask=False, subfield=None):
'''
Return content of the given instance and field name encrypted.
@ -184,6 +187,14 @@ def encrypt_field(instance, field_name, ask=False, subfield=None):
b64data = base64.b64encode(encrypted)
return '$encrypted$%s$%s' % ('AES', b64data)
def decrypt_value(encryption_key, value):
algo, b64data = value[len('$encrypted$'):].split('$', 1)
if algo != 'AES':
raise ValueError('unsupported algorithm: %s' % algo)
encrypted = base64.b64decode(b64data)
cipher = AES.new(encryption_key, AES.MODE_ECB)
value = cipher.decrypt(encrypted)
return value.rstrip('\x00')
def decrypt_field(instance, field_name, subfield=None):
'''
@ -194,15 +205,13 @@ def decrypt_field(instance, field_name, subfield=None):
value = value[subfield]
if not value or not value.startswith('$encrypted$'):
return value
algo, b64data = value[len('$encrypted$'):].split('$', 1)
if algo != 'AES':
raise ValueError(_('unsupported algorithm: %s') % algo)
encrypted = base64.b64decode(b64data)
key = get_encryption_key(instance, field_name)
cipher = AES.new(key, AES.MODE_ECB)
value = cipher.decrypt(encrypted)
return value.rstrip('\x00')
return decrypt_value(key, value)
def decrypt_field_value(pk, field_name, value):
key = get_encryption_key_for_pk(pk, field_name)
return decrypt_value(key, value)
def update_scm_url(scm_type, url, username=True, password=True,
check_special_cases=True, scp_format=False):