From ce9434314fb4851e1573270d9b6a07d88d521ca1 Mon Sep 17 00:00:00 2001 From: Matthew Jones Date: Mon, 10 Nov 2014 12:16:50 -0500 Subject: [PATCH 1/6] Add a metadata file to the tower home directory that lists the version of Tower --- awx/main/management/commands/tower_version.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 awx/main/management/commands/tower_version.py diff --git a/awx/main/management/commands/tower_version.py b/awx/main/management/commands/tower_version.py new file mode 100644 index 0000000000..17b9c1673b --- /dev/null +++ b/awx/main/management/commands/tower_version.py @@ -0,0 +1,13 @@ +# Copyright (c) 2014 Ansible, Inc. +# All Rights Reserved + +from django.core.management.base import BaseCommand + +from awx import __version__ as tower_version + +class Command(BaseCommand): + + help = 'Emit the Tower version and exit' + + def handle(self, *args, **options): + self.stdout.write(tower_version) From 4e494469c98b876f85e175471cb3942966e5fc9b Mon Sep 17 00:00:00 2001 From: Matthew Jones Date: Mon, 10 Nov 2014 12:22:20 -0500 Subject: [PATCH 2/6] Use the normal version checker from tower manage --- awx/main/management/commands/tower_version.py | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 awx/main/management/commands/tower_version.py diff --git a/awx/main/management/commands/tower_version.py b/awx/main/management/commands/tower_version.py deleted file mode 100644 index 17b9c1673b..0000000000 --- a/awx/main/management/commands/tower_version.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright (c) 2014 Ansible, Inc. -# All Rights Reserved - -from django.core.management.base import BaseCommand - -from awx import __version__ as tower_version - -class Command(BaseCommand): - - help = 'Emit the Tower version and exit' - - def handle(self, *args, **options): - self.stdout.write(tower_version) From 309dba969373393b635ae7299a27a863c3721c8a Mon Sep 17 00:00:00 2001 From: Matthew Jones Date: Mon, 10 Nov 2014 13:58:29 -0500 Subject: [PATCH 3/6] Wording changes for the system job descriptions as proposed by @mpdehaan --- awx/main/migrations/0059_v210_changes.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/awx/main/migrations/0059_v210_changes.py b/awx/main/migrations/0059_v210_changes.py index 016e08a9fe..89d12fa334 100644 --- a/awx/main/migrations/0059_v210_changes.py +++ b/awx/main/migrations/0059_v210_changes.py @@ -9,18 +9,18 @@ from awx.main.models import * class Migration(DataMigration): def forwards(self, orm): - SystemJobTemplate(name='Delete Old Jobs', - description="Run a job to delete jobs that are older than a given number of days", + SystemJobTemplate(name='Cleanup Job Details', + description="Remove job history older than X days", job_type="cleanup_jobs", created=now(), modified=now()).save() SystemJobTemplate(name='Cleanup Deleted Data', - description="Run a job to cleanup any deleted objects that are older than a given number of days", + description="Remove deleted object history older than X days", job_type="cleanup_deleted", created=now(), modified=now()).save() SystemJobTemplate(name='Cleanup Activity Stream', - description="Run a job to purge activity stream data that's older than a given number of days", + description="Remove activity stream history older than X days", job_type="cleanup_activitystream", created=now(), modified=now()).save() From 73636ef1a0e3ae3ed0df5a2cbe21dcbb9b7925fe Mon Sep 17 00:00:00 2001 From: Chris Church Date: Mon, 10 Nov 2014 14:16:05 -0500 Subject: [PATCH 4/6] Update ec2 inventory to include instance_filters support (https://github.com/ansible/ansible/pull/8822). --- awx/plugins/inventory/ec2.ini.example | 20 ++++++++++++++++++++ awx/plugins/inventory/ec2.py | 22 ++++++++++++++++++++-- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/awx/plugins/inventory/ec2.ini.example b/awx/plugins/inventory/ec2.ini.example index a0c8672394..c66bf309b1 100644 --- a/awx/plugins/inventory/ec2.ini.example +++ b/awx/plugins/inventory/ec2.ini.example @@ -73,3 +73,23 @@ nested_groups = False # If you want to exclude any hosts that match a certain regular expression # pattern_exclude = stage-* + +# Instance filters can be used to control which instances are retrieved for +# inventory. For the full list of possible filters, please read the EC2 API +# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters +# Filters are key/value pairs separated by '=', to list multiple filters use +# a list separated by commas. See examples below. + +# Retrieve only instances with (key=value) env=stage tag +# instance_filters = tag:env=stage + +# Retrieve only instances with role=webservers OR role=dbservers tag +# instance_filters = tag:role=webservers,tag:role=dbservers + +# Retrieve only t1.micro instances OR instances with tag env=stage +# instance_filters = instance-type=t1.micro,tag:env=stage + +# You can use wildcards in filter values also. Below will list instances which +# tag Name value matches webservers1* +# (ex. webservers15, webservers1a, webservers123 etc) +# instance_filters = tag:Name=webservers1* diff --git a/awx/plugins/inventory/ec2.py b/awx/plugins/inventory/ec2.py index c8e6d6e7f3..aec6473be6 100755 --- a/awx/plugins/inventory/ec2.py +++ b/awx/plugins/inventory/ec2.py @@ -123,6 +123,7 @@ from boto import ec2 from boto import rds from boto import route53 import ConfigParser +from collections import defaultdict try: import json @@ -257,6 +258,8 @@ class Ec2Inventory(object): pattern_include = config.get('ec2', 'pattern_include') if pattern_include and len(pattern_include) > 0: self.pattern_include = re.compile(pattern_include) + else: + self.pattern_include = None except ConfigParser.NoOptionError, e: self.pattern_include = None @@ -265,8 +268,17 @@ class Ec2Inventory(object): pattern_exclude = config.get('ec2', 'pattern_exclude'); if pattern_exclude and len(pattern_exclude) > 0: self.pattern_exclude = re.compile(pattern_exclude) + else: + self.pattern_exclude = None except ConfigParser.NoOptionError, e: - self.pattern_exclude = '' + self.pattern_exclude = None + + # Instance filters (see boto and EC2 API docs) + self.ec2_instance_filters = defaultdict(list) + if config.has_option('ec2', 'instance_filters'): + for x in config.get('ec2', 'instance_filters', '').split(','): + filter_key, filter_value = x.split('=') + self.ec2_instance_filters[filter_key].append(filter_value) def parse_cli_args(self): ''' Command line argument processing ''' @@ -312,7 +324,13 @@ class Ec2Inventory(object): print("region name: %s likely not supported, or AWS is down. connection to region failed." % region) sys.exit(1) - reservations = conn.get_all_instances() + reservations = [] + if self.ec2_instance_filters: + for filter_key, filter_values in self.ec2_instance_filters.iteritems(): + reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values })) + else: + reservations = conn.get_all_instances() + for reservation in reservations: for instance in reservation.instances: self.add_instance(instance, region) From 0de53886dad62c2ada8088322b399d758f68e918 Mon Sep 17 00:00:00 2001 From: Matthew Jones Date: Mon, 10 Nov 2014 14:44:09 -0500 Subject: [PATCH 5/6] Disallow multiple schedules for System Job Templates --- awx/api/views.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/awx/api/views.py b/awx/api/views.py index 08015cdfc6..0afb08f666 100644 --- a/awx/api/views.py +++ b/awx/api/views.py @@ -1766,6 +1766,12 @@ class SystemJobTemplateSchedulesList(SubListCreateAPIView): relationship = 'schedules' parent_key = 'unified_job_template' + def post(self, request, *args, **kwargs): + system_job = self.get_parent_object() + if system_job.schedules.count() > 0: + return Response({"error": "Multiple schedules for Systems Jobs is not allowed"}, status=status.HTTP_400_BAD_REQUEST) + return super(SystemJobTemplateSchedulesList, self).post(request, *args, **kwargs) + class SystemJobTemplateJobsList(SubListAPIView): model = SystemJob From c4e2463db1fe2f156fc112b3d8c8c97c6af070a0 Mon Sep 17 00:00:00 2001 From: Matthew Jones Date: Mon, 10 Nov 2014 15:12:14 -0500 Subject: [PATCH 6/6] Sanity check for tower version metadata file in wsgi bootstrap --- awx/wsgi.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/awx/wsgi.py b/awx/wsgi.py index f7e84dbbf6..6baa09a2f6 100644 --- a/awx/wsgi.py +++ b/awx/wsgi.py @@ -14,6 +14,20 @@ https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/ from awx import prepare_env prepare_env() +import os +import logging +from django.conf import settings +from awx import __version__ as tower_version +logger = logging.getLogger('awx.main.models.jobs') +try: + fd = open("/var/lib/awx/.tower_version", "r") + if fd.read().strip() != tower_version: + logger.error("Tower Versions don't match, potential invalid setup detected") + raise Exception("Tower Versions don't match, potential invalid setup detected") +except Exception: + logger.error("Missing tower version metadata at /var/lib/awx/.tower_version") + raise Exception("Missing tower version metadata at /var/lib/awx/.tower_version") + # Return the default Django WSGI application. from django.core.wsgi import get_wsgi_application application = get_wsgi_application()