Merge pull request #3917 from chrismeyersfsu/task-manager_prov_callback_inv_sync_dedup

on host callback, upate dynamic inv only once
This commit is contained in:
Chris Meyers
2016-11-08 15:45:38 -05:00
committed by GitHub
3 changed files with 36 additions and 10 deletions

View File

@@ -235,7 +235,12 @@ class TaskManager():
dependencies.append(project_task) dependencies.append(project_task)
# Inventory created 2 seconds behind job # 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']): 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']): if self.graph.should_update_related_inventory_source(task, inventory_source_task['id']):
inventory_task = self.create_inventory_update(task, inventory_source_task) inventory_task = self.create_inventory_update(task, inventory_source_task)
dependencies.append(inventory_task) dependencies.append(inventory_task)

View File

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

View File

@@ -156,17 +156,20 @@ def get_awx_version():
return __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. Generate key for encrypted password based on instance pk and field name.
''' '''
from django.conf import settings from django.conf import settings
h = hashlib.sha1() h = hashlib.sha1()
h.update(settings.SECRET_KEY) h.update(settings.SECRET_KEY)
h.update(str(instance.pk)) h.update(str(pk))
h.update(field_name) h.update(field_name)
return h.digest()[:16] 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): def encrypt_field(instance, field_name, ask=False, subfield=None):
''' '''
Return content of the given instance and field name encrypted. Return content of the given instance and field name encrypted.
@@ -185,6 +188,14 @@ def encrypt_field(instance, field_name, ask=False, subfield=None):
b64data = base64.b64encode(encrypted) b64data = base64.b64encode(encrypted)
return '$encrypted$%s$%s' % ('AES', b64data) 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): def decrypt_field(instance, field_name, subfield=None):
''' '''
@@ -195,15 +206,13 @@ def decrypt_field(instance, field_name, subfield=None):
value = value[subfield] value = value[subfield]
if not value or not value.startswith('$encrypted$'): if not value or not value.startswith('$encrypted$'):
return value 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) 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, def update_scm_url(scm_type, url, username=True, password=True,
check_special_cases=True, scp_format=False): check_special_cases=True, scp_format=False):