From bc763eab57de1e682980b58bac7b9b3b5b9b448d Mon Sep 17 00:00:00 2001 From: Luke Sneeringer Date: Wed, 8 Oct 2014 12:01:58 -0500 Subject: [PATCH] Know how to spot an HA environment. --- awx/main/ha.py | 23 +++++++++++++++++++++++ awx/main/middleware.py | 2 +- awx/main/utils.py | 24 ++++++++++++++++++++++-- 3 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 awx/main/ha.py diff --git a/awx/main/ha.py b/awx/main/ha.py new file mode 100644 index 0000000000..1cd4540a87 --- /dev/null +++ b/awx/main/ha.py @@ -0,0 +1,23 @@ +# Copyright (c) 2014 Ansible, Inc. +# All Rights Reserved. + +from django.conf import settings + +from awx.main.models import Instance + + +def is_ha_environment(): + """Return True if this is an HA environment, and False + otherwise. + """ + # If there are two or more instances, then we are in an HA environment. + if Instance.objects.count() > 1: + return True + + # If the database is not local, then we are in an HA environment. + host = settings.DATABASES['default'].get('host', 'localhost') + if host and host.lower() not in ('127.0.0.1', 'localhost'): + return True + + # We are not in an HA environment. + return False diff --git a/awx/main/middleware.py b/awx/main/middleware.py index b09d5405f5..d0c05c89da 100644 --- a/awx/main/middleware.py +++ b/awx/main/middleware.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014 AnsibleWorks, Inc. +# Copyright (c) 2014 Ansible, Inc. # All Rights Reserved. import json diff --git a/awx/main/utils.py b/awx/main/utils.py index 4e4482d4eb..87635d5968 100644 --- a/awx/main/utils.py +++ b/awx/main/utils.py @@ -21,10 +21,13 @@ from Crypto.Cipher import AES # ZeroMQ import zmq + __all__ = ['get_object_or_400', 'get_object_or_403', 'camelcase_to_underscore', 'get_ansible_version', 'get_awx_version', 'update_scm_url', - 'get_type_for_model', 'get_model_for_type', 'ignore_inventory_computed_fields', - 'ignore_inventory_group_removal', '_inventory_updates'] + 'get_type_for_model', 'get_model_for_type', + 'ignore_inventory_computed_fields', 'ignore_inventory_group_removal', + '_inventory_updates'] + def get_object_or_400(klass, *args, **kwargs): ''' @@ -40,6 +43,7 @@ def get_object_or_400(klass, *args, **kwargs): except queryset.model.MultipleObjectsReturned, e: raise ParseError(*e.args) + def get_object_or_403(klass, *args, **kwargs): ''' Return a single object from the given model or queryset based on the query @@ -54,6 +58,7 @@ def get_object_or_403(klass, *args, **kwargs): except queryset.model.MultipleObjectsReturned, e: raise PermissionDenied(*e.args) + def camelcase_to_underscore(s): ''' Convert CamelCase names to lowercase_with_underscore. @@ -61,6 +66,7 @@ def camelcase_to_underscore(s): s = re.sub(r'(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))', '_\\1', s) return s.lower().strip('_') + class RequireDebugTrueOrTest(logging.Filter): ''' Logging filter to output when in DEBUG mode or running tests. @@ -70,6 +76,7 @@ class RequireDebugTrueOrTest(logging.Filter): from django.conf import settings return settings.DEBUG or 'test' in sys.argv + def get_ansible_version(): ''' Return Ansible version installed. @@ -83,6 +90,7 @@ def get_ansible_version(): except: return 'unknown' + def get_awx_version(): ''' Return Ansible Tower version as reported by setuptools. @@ -94,6 +102,7 @@ def get_awx_version(): except: return __version__ + def get_encryption_key(instance, field_name): ''' Generate key for encrypted password based on instance pk and field name. @@ -105,6 +114,7 @@ def get_encryption_key(instance, field_name): h.update(field_name) return h.digest()[:16] + def encrypt_field(instance, field_name, ask=False): ''' Return content of the given instance and field name encrypted. @@ -121,6 +131,7 @@ def encrypt_field(instance, field_name, ask=False): b64data = base64.b64encode(encrypted) return '$encrypted$%s$%s' % ('AES', b64data) + def decrypt_field(instance, field_name): ''' Return content of the given instance and field name decrypted. @@ -137,6 +148,7 @@ def decrypt_field(instance, field_name): value = cipher.decrypt(encrypted) return value.rstrip('\x00') + def update_scm_url(scm_type, url, username=True, password=True, check_special_cases=True): ''' @@ -233,6 +245,7 @@ def update_scm_url(scm_type, url, username=True, password=True, parts.query, parts.fragment]) return new_url + def model_instance_diff(old, new, serializer_mapping=None): """ Calculate the differences between two model instances. One of the instances may be None (i.e., a newly @@ -283,6 +296,7 @@ def model_instance_diff(old, new, serializer_mapping=None): return diff + def model_to_dict(obj, serializer_mapping=None): """ Serialize a model instance to a dictionary as best as possible @@ -309,6 +323,7 @@ def model_to_dict(obj, serializer_mapping=None): attr_d[field.name] = "hidden" return attr_d + def get_type_for_model(model): ''' Return type name for a given model class. @@ -317,6 +332,7 @@ def get_type_for_model(model): opts = get_concrete_model(model)._meta return camelcase_to_underscore(opts.object_name) + def get_model_for_type(type): ''' Return model class for a given type name. @@ -331,6 +347,7 @@ def get_model_for_type(type): if type == ct_type: return ct_model + def get_system_task_capacity(): ''' Measure system memory and use it as a baseline for determining the system's capacity @@ -345,6 +362,7 @@ def get_system_task_capacity(): return 50 return 50 + ((int(total_mem_value) / 1024) - 2) * 75 + def emit_websocket_notification(endpoint, event, payload): from django.conf import settings if getattr(settings, 'SOCKETIO_NOTIFICATION_PORT', None): @@ -357,6 +375,7 @@ def emit_websocket_notification(endpoint, event, payload): _inventory_updates = threading.local() + @contextlib.contextmanager def ignore_inventory_computed_fields(): ''' @@ -369,6 +388,7 @@ def ignore_inventory_computed_fields(): finally: _inventory_updates.is_updating = previous_value + @contextlib.contextmanager def ignore_inventory_group_removal(): '''