From fcdd422b5f2cf8c8d24d6e166497a82c3ca8a2f5 Mon Sep 17 00:00:00 2001 From: Tomas Date: Wed, 7 Jul 2021 17:53:08 -0300 Subject: [PATCH 01/24] Actualizadas las dependecias. --- DEPRECATED_BACKUP.TXT | 11 + cabot/__init__.py | 2 +- cabot/cabot_config.py | 3 +- cabot/cabotapp/alert.py | 2 +- cabot/cabotapp/graphite.py | 4 +- cabot/cabotapp/migrations/0001_initial.py | 26 +- .../migrations/0003_auto_20170201_1045.py | 6 +- .../migrations/0008_auto_20210707_1645.py | 260 ++++++++++++++++++ cabot/cabotapp/models/base.py | 19 +- cabot/cabotapp/models/jenkins_check_plugin.py | 2 +- cabot/cabotapp/tests/test_urlprefix.py | 2 +- cabot/cabotapp/tests/tests_basic.py | 2 +- cabot/cabotapp/views.py | 16 +- cabot/settings.py | 31 ++- cabot/templates/base_public.html | 2 +- cabot/templates/cabotapp/about.html | 2 +- cabot/templates/cabotapp/instance_detail.html | 2 +- cabot/templates/cabotapp/service_detail.html | 2 +- .../templates/cabotapp/statuscheck_form.html | 2 +- .../cabotapp/statuscheckresult_detail.html | 2 +- cabot/urls.py | 15 +- cabot/version.py | 2 +- conf/default.env | 2 +- docker-compose.yml | 1 + requiements.txt | 111 ++++++++ 25 files changed, 464 insertions(+), 65 deletions(-) create mode 100644 DEPRECATED_BACKUP.TXT create mode 100644 cabot/cabotapp/migrations/0008_auto_20210707_1645.py create mode 100644 requiements.txt diff --git a/DEPRECATED_BACKUP.TXT b/DEPRECATED_BACKUP.TXT new file mode 100644 index 000000000..4e6672b0c --- /dev/null +++ b/DEPRECATED_BACKUP.TXT @@ -0,0 +1,11 @@ +MIDDLEWARE= + + ''' + 'whitenoise.middleware.WhiteNoiseMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + ''' \ No newline at end of file diff --git a/cabot/__init__.py b/cabot/__init__.py index 8989229b5..f091ecefb 100644 --- a/cabot/__init__.py +++ b/cabot/__init__.py @@ -4,4 +4,4 @@ # Django starts so that shared_task will use this app. from .celery import app as celery_app -from .version import version +#from .version import version diff --git a/cabot/cabot_config.py b/cabot/cabot_config.py index fb3d440ae..2a90c7b38 100644 --- a/cabot/cabot_config.py +++ b/cabot/cabot_config.py @@ -30,4 +30,5 @@ ACKNOWLEDGEMENT_EXPIRY = int(os.environ.get('ACKNOWLEDGEMENT_EXPIRY', 20)) # Default plugins are used if the user has not specified. -CABOT_PLUGINS_ENABLED = os.environ.get('CABOT_PLUGINS_ENABLED', 'cabot_alert_hipchat,cabot_alert_twilio,cabot_alert_email') +#CABOT_PLUGINS_ENABLED = os.environ.get('CABOT_PLUGINS_ENABLED', 'cabot_alert_hipchat,cabot_alert_twilio,cabot_alert_email') +CABOT_PLUGINS_ENABLED = os.environ.get('CABOT_PLUGINS_ENABLED', 'cabot_alert_email') \ No newline at end of file diff --git a/cabot/cabotapp/alert.py b/cabot/cabotapp/alert.py index da634466e..245672258 100644 --- a/cabot/cabotapp/alert.py +++ b/cabot/cabotapp/alert.py @@ -40,7 +40,7 @@ def send_alert(self, service, users, duty_officers): class AlertPluginUserData(PolymorphicModel): title = models.CharField(max_length=30, editable=False) - user = models.ForeignKey('UserProfile', editable=False) + user = models.ForeignKey('UserProfile', editable=False , on_delete=models.CASCADE) class Meta: unique_together = ('title', 'user',) diff --git a/cabot/cabotapp/graphite.py b/cabot/cabotapp/graphite.py index 3666e6e9c..4b5ecb59c 100644 --- a/cabot/cabotapp/graphite.py +++ b/cabot/cabotapp/graphite.py @@ -30,7 +30,7 @@ def get_data(target_pattern, mins_to_check=None): def get_matching_metrics(pattern): - print 'Getting metrics matching %s' % pattern + print('Getting metrics matching %s' % pattern) resp = requests.get( graphite_api + 'metrics/find/', auth=auth, params={ @@ -71,7 +71,7 @@ def parse_metric(metric, mins_to_check=5, utcnow=None): } try: data = get_data(metric, mins_to_check) - except requests.exceptions.RequestException, e: + except requests.exceptions.RequestException as e: ret['error'] = 'Error getting data from Graphite: %s' % e ret['raw'] = ret['error'] logging.error('Error getting data from Graphite: %s' % e) diff --git a/cabot/cabotapp/migrations/0001_initial.py b/cabot/cabotapp/migrations/0001_initial.py index 5324e7472..28e84dadb 100644 --- a/cabot/cabotapp/migrations/0001_initial.py +++ b/cabot/cabotapp/migrations/0001_initial.py @@ -19,7 +19,7 @@ class Migration(migrations.Migration): ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('time', models.DateTimeField()), ('cancelled_time', models.DateTimeField(null=True, blank=True)), - ('cancelled_user', models.ForeignKey(related_name='cancelleduser_set', blank=True, to=settings.AUTH_USER_MODEL, null=True)), + ('cancelled_user', models.ForeignKey(related_name='cancelleduser_set', blank=True, to=settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE)), ], options={ }, @@ -31,7 +31,7 @@ class Migration(migrations.Migration): ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('title', models.CharField(unique=True, max_length=30, editable=False)), ('enabled', models.BooleanField(default=True)), - ('polymorphic_ctype', models.ForeignKey(related_name='polymorphic_cabotapp.alertplugin_set', editable=False, to='contenttypes.ContentType', null=True)), + ('polymorphic_ctype', models.ForeignKey(related_name='polymorphic_cabotapp.alertplugin_set', editable=False, to='contenttypes.ContentType', null=True, on_delete=models.CASCADE)), ], options={ 'abstract': False, @@ -43,7 +43,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('title', models.CharField(max_length=30, editable=False)), - ('polymorphic_ctype', models.ForeignKey(related_name='polymorphic_cabotapp.alertpluginuserdata_set', editable=False, to='contenttypes.ContentType', null=True)), + ('polymorphic_ctype', models.ForeignKey(related_name='polymorphic_cabotapp.alertpluginuserdata_set', editable=False, to='contenttypes.ContentType', null=True, on_delete=models.CASCADE)), ], options={ }, @@ -82,7 +82,7 @@ class Migration(migrations.Migration): ('num_checks_failing', models.IntegerField(default=0)), ('overall_status', models.TextField(default=b'PASSING')), ('did_send_alert', models.IntegerField(default=False)), - ('instance', models.ForeignKey(related_name='snapshots', to='cabotapp.Instance')), + ('instance', models.ForeignKey(related_name='snapshots', to='cabotapp.Instance', on_delete=models.CASCADE)), ], options={ 'abstract': False, @@ -123,7 +123,7 @@ class Migration(migrations.Migration): ('num_checks_failing', models.IntegerField(default=0)), ('overall_status', models.TextField(default=b'PASSING')), ('did_send_alert', models.IntegerField(default=False)), - ('service', models.ForeignKey(related_name='snapshots', to='cabotapp.Service')), + ('service', models.ForeignKey(related_name='snapshots', to='cabotapp.Service', on_delete=models.CASCADE)), ], options={ 'abstract': False, @@ -139,7 +139,7 @@ class Migration(migrations.Migration): ('uid', models.TextField()), ('last_modified', models.DateTimeField()), ('deleted', models.BooleanField(default=False)), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], options={ }, @@ -170,8 +170,8 @@ class Migration(migrations.Migration): ('timeout', models.IntegerField(default=30, help_text=b'Time out after this many seconds.', null=True)), ('verify_ssl_certificate', models.BooleanField(default=True, help_text=b'Set to false to allow not try to verify ssl certificates (default True)')), ('max_queued_build_time', models.IntegerField(help_text=b'Alert if build queued for more than this many minutes.', null=True, blank=True)), - ('created_by', models.ForeignKey(to=settings.AUTH_USER_MODEL, null=True)), - ('polymorphic_ctype', models.ForeignKey(related_name='polymorphic_cabotapp.statuscheck_set', editable=False, to='contenttypes.ContentType', null=True)), + ('created_by', models.ForeignKey(to=settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE)), + ('polymorphic_ctype', models.ForeignKey(related_name='polymorphic_cabotapp.statuscheck_set', editable=False, to='contenttypes.ContentType', null=True, on_delete=models.CASCADE)), ], options={ 'ordering': ['name'], @@ -189,7 +189,7 @@ class Migration(migrations.Migration): ('succeeded', models.BooleanField(default=False)), ('error', models.TextField(null=True)), ('job_number', models.PositiveIntegerField(null=True)), - ('check', models.ForeignKey(to='cabotapp.StatusCheck')), + ('check', models.ForeignKey(to='cabotapp.StatusCheck', on_delete=models.CASCADE)), ], options={ 'ordering': ['-time_complete'], @@ -203,7 +203,7 @@ class Migration(migrations.Migration): ('mobile_number', models.CharField(default=b'', max_length=20, blank=True)), ('hipchat_alias', models.CharField(default=b'', max_length=50, blank=True)), ('fallback_alert_user', models.BooleanField(default=False)), - ('user', models.OneToOneField(related_name='profile', to=settings.AUTH_USER_MODEL)), + ('user', models.OneToOneField(related_name='profile', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], options={ }, @@ -240,7 +240,7 @@ class Migration(migrations.Migration): migrations.AddField( model_name='alertpluginuserdata', name='user', - field=models.ForeignKey(editable=False, to='cabotapp.UserProfile'), + field=models.ForeignKey(editable=False, to='cabotapp.UserProfile', on_delete=models.CASCADE), preserve_default=True, ), migrations.AlterUniqueTogether( @@ -250,13 +250,13 @@ class Migration(migrations.Migration): migrations.AddField( model_name='alertacknowledgement', name='service', - field=models.ForeignKey(to='cabotapp.Service'), + field=models.ForeignKey(to='cabotapp.Service', on_delete=models.CASCADE), preserve_default=True, ), migrations.AddField( model_name='alertacknowledgement', name='user', - field=models.ForeignKey(to=settings.AUTH_USER_MODEL), + field=models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE), preserve_default=True, ), migrations.CreateModel( diff --git a/cabot/cabotapp/migrations/0003_auto_20170201_1045.py b/cabot/cabotapp/migrations/0003_auto_20170201_1045.py index aec778aae..da979a391 100644 --- a/cabot/cabotapp/migrations/0003_auto_20170201_1045.py +++ b/cabot/cabotapp/migrations/0003_auto_20170201_1045.py @@ -14,16 +14,16 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='alertplugin', name='polymorphic_ctype', - field=models.ForeignKey(related_name='polymorphic_cabotapp.alertplugin_set+', editable=False, to='contenttypes.ContentType', null=True), + field=models.ForeignKey(related_name='polymorphic_cabotapp.alertplugin_set+', editable=False, to='contenttypes.ContentType', null=True, on_delete=models.CASCADE), ), migrations.AlterField( model_name='alertpluginuserdata', name='polymorphic_ctype', - field=models.ForeignKey(related_name='polymorphic_cabotapp.alertpluginuserdata_set+', editable=False, to='contenttypes.ContentType', null=True), + field=models.ForeignKey(related_name='polymorphic_cabotapp.alertpluginuserdata_set+', editable=False, to='contenttypes.ContentType', null=True, on_delete=models.CASCADE), ), migrations.AlterField( model_name='statuscheck', name='polymorphic_ctype', - field=models.ForeignKey(related_name='polymorphic_cabotapp.statuscheck_set+', editable=False, to='contenttypes.ContentType', null=True), + field=models.ForeignKey(related_name='polymorphic_cabotapp.statuscheck_set+', editable=False, to='contenttypes.ContentType', null=True, on_delete=models.CASCADE), ), ] diff --git a/cabot/cabotapp/migrations/0008_auto_20210707_1645.py b/cabot/cabotapp/migrations/0008_auto_20210707_1645.py new file mode 100644 index 000000000..42d509b0a --- /dev/null +++ b/cabot/cabotapp/migrations/0008_auto_20210707_1645.py @@ -0,0 +1,260 @@ +# Generated by Django 3.2.5 on 2021-07-07 16:45 + +from django.conf import settings +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('cabotapp', '0007_statuscheckresult_consecutive_failures'), + ] + + operations = [ + migrations.AlterModelOptions( + name='alertplugin', + options={'base_manager_name': 'objects'}, + ), + migrations.AlterModelOptions( + name='graphitestatuscheck', + options={'base_manager_name': 'objects'}, + ), + migrations.AlterModelOptions( + name='httpstatuscheck', + options={'base_manager_name': 'objects'}, + ), + migrations.AlterModelOptions( + name='icmpstatuscheck', + options={'base_manager_name': 'objects'}, + ), + migrations.AlterModelOptions( + name='jenkinsstatuscheck', + options={'base_manager_name': 'objects'}, + ), + migrations.AlterModelOptions( + name='statuscheck', + options={'base_manager_name': 'objects', 'ordering': ['name']}, + ), + migrations.AlterField( + model_name='instance', + name='address', + field=models.TextField(blank=True, help_text='Address (IP/Hostname) of service.'), + ), + migrations.AlterField( + model_name='instance', + name='alerts', + field=models.ManyToManyField(blank=True, help_text='Alerts channels through which you wish to be notified', to='cabotapp.AlertPlugin'), + ), + migrations.AlterField( + model_name='instance', + name='alerts_enabled', + field=models.BooleanField(default=True, help_text='Alert when this service is not healthy.'), + ), + migrations.AlterField( + model_name='instance', + name='hackpad_id', + field=models.TextField(blank=True, help_text='Gist, Hackpad or Refheap js embed with recovery instructions e.g. https://you.hackpad.com/some_document.js', null=True, verbose_name='Embedded recovery instructions'), + ), + migrations.AlterField( + model_name='instance', + name='old_overall_status', + field=models.TextField(default='PASSING'), + ), + migrations.AlterField( + model_name='instance', + name='overall_status', + field=models.TextField(default='PASSING'), + ), + migrations.AlterField( + model_name='instance', + name='runbook_link', + field=models.TextField(blank=True, help_text='Link to the service runbook on your wiki.'), + ), + migrations.AlterField( + model_name='instance', + name='status_checks', + field=models.ManyToManyField(blank=True, help_text='Checks used to calculate service status.', to='cabotapp.StatusCheck'), + ), + migrations.AlterField( + model_name='instance', + name='telephone_alert', + field=models.BooleanField(default=False, help_text='Must be enabled, and check importance set to Critical, to receive telephone alerts.'), + ), + migrations.AlterField( + model_name='instance', + name='users_to_notify', + field=models.ManyToManyField(blank=True, help_text='Users who should receive alerts.', to=settings.AUTH_USER_MODEL), + ), + migrations.AlterField( + model_name='instancestatussnapshot', + name='overall_status', + field=models.TextField(default='PASSING'), + ), + migrations.AlterField( + model_name='service', + name='alerts', + field=models.ManyToManyField(blank=True, help_text='Alerts channels through which you wish to be notified', to='cabotapp.AlertPlugin'), + ), + migrations.AlterField( + model_name='service', + name='alerts_enabled', + field=models.BooleanField(default=True, help_text='Alert when this service is not healthy.'), + ), + migrations.AlterField( + model_name='service', + name='hackpad_id', + field=models.TextField(blank=True, help_text='Gist, Hackpad or Refheap js embed with recovery instructions e.g. https://you.hackpad.com/some_document.js', null=True, verbose_name='Embedded recovery instructions'), + ), + migrations.AlterField( + model_name='service', + name='instances', + field=models.ManyToManyField(blank=True, help_text='Instances this service is running on.', to='cabotapp.Instance'), + ), + migrations.AlterField( + model_name='service', + name='is_public', + field=models.BooleanField(default=False, help_text='The service will be shown in the public home', verbose_name='Is Public'), + ), + migrations.AlterField( + model_name='service', + name='old_overall_status', + field=models.TextField(default='PASSING'), + ), + migrations.AlterField( + model_name='service', + name='overall_status', + field=models.TextField(default='PASSING'), + ), + migrations.AlterField( + model_name='service', + name='runbook_link', + field=models.TextField(blank=True, help_text='Link to the service runbook on your wiki.'), + ), + migrations.AlterField( + model_name='service', + name='status_checks', + field=models.ManyToManyField(blank=True, help_text='Checks used to calculate service status.', to='cabotapp.StatusCheck'), + ), + migrations.AlterField( + model_name='service', + name='telephone_alert', + field=models.BooleanField(default=False, help_text='Must be enabled, and check importance set to Critical, to receive telephone alerts.'), + ), + migrations.AlterField( + model_name='service', + name='url', + field=models.TextField(blank=True, help_text='URL of service.'), + ), + migrations.AlterField( + model_name='service', + name='users_to_notify', + field=models.ManyToManyField(blank=True, help_text='Users who should receive alerts.', to=settings.AUTH_USER_MODEL), + ), + migrations.AlterField( + model_name='servicestatussnapshot', + name='overall_status', + field=models.TextField(default='PASSING'), + ), + migrations.AlterField( + model_name='statuscheck', + name='active', + field=models.BooleanField(default=True, help_text='If not active, check will not be used to calculate service status and will not trigger alerts.'), + ), + migrations.AlterField( + model_name='statuscheck', + name='allowed_num_failures', + field=models.IntegerField(default=0, help_text='The maximum number of data series (metrics) you expect to fail. For example, you might be OK with 2 out of 3 webservers having OK load (1 failing), but not 1 out of 3 (2 failing).', null=True), + ), + migrations.AlterField( + model_name='statuscheck', + name='calculated_status', + field=models.CharField(blank=True, choices=[('passing', 'passing'), ('intermittent', 'intermittent'), ('failing', 'failing')], default='passing', max_length=50), + ), + migrations.AlterField( + model_name='statuscheck', + name='check_type', + field=models.CharField(choices=[('>', 'Greater than'), ('>=', 'Greater than or equal'), ('<', 'Less than'), ('<=', 'Less than or equal'), ('==', 'Equal to')], max_length=100, null=True), + ), + migrations.AlterField( + model_name='statuscheck', + name='debounce', + field=models.IntegerField(default=0, help_text='Number of successive failures permitted before check will be marked as failed. Default is 0, i.e. fail on first failure.', null=True), + ), + migrations.AlterField( + model_name='statuscheck', + name='endpoint', + field=models.TextField(help_text='HTTP(S) endpoint to poll.', null=True, validators=[django.core.validators.URLValidator()]), + ), + migrations.AlterField( + model_name='statuscheck', + name='expected_num_hosts', + field=models.IntegerField(default=0, help_text='The minimum number of data series (hosts) you expect to see.', null=True), + ), + migrations.AlterField( + model_name='statuscheck', + name='frequency', + field=models.IntegerField(default=5, help_text='Minutes between each check.'), + ), + migrations.AlterField( + model_name='statuscheck', + name='importance', + field=models.CharField(choices=[('WARNING', 'Warning'), ('ERROR', 'Error'), ('CRITICAL', 'Critical')], default='ERROR', help_text='Severity level of a failure. Critical alerts are for failures you want to wake you up at 2am, Errors are things you can sleep through but need to fix in the morning, and warnings for less important things.', max_length=30), + ), + migrations.AlterField( + model_name='statuscheck', + name='max_queued_build_time', + field=models.IntegerField(blank=True, help_text='Alert if build queued for more than this many minutes.', null=True), + ), + migrations.AlterField( + model_name='statuscheck', + name='metric', + field=models.TextField(help_text='fully.qualified.name of the Graphite metric you want to watch. This can be any valid Graphite expression, including wildcards, multiple hosts, etc.', null=True), + ), + migrations.AlterField( + model_name='statuscheck', + name='password', + field=models.TextField(blank=True, help_text='Basic auth password.', null=True), + ), + migrations.AlterField( + model_name='statuscheck', + name='status_code', + field=models.TextField(default=200, help_text='Status code expected from endpoint.', null=True), + ), + migrations.AlterField( + model_name='statuscheck', + name='text_match', + field=models.TextField(blank=True, help_text='Regex to match against source of page.', null=True), + ), + migrations.AlterField( + model_name='statuscheck', + name='timeout', + field=models.IntegerField(default=30, help_text='Time out after this many seconds.', null=True), + ), + migrations.AlterField( + model_name='statuscheck', + name='username', + field=models.TextField(blank=True, help_text='Basic auth username.', null=True), + ), + migrations.AlterField( + model_name='statuscheck', + name='value', + field=models.TextField(help_text='If this expression evaluates to true, the check will fail (possibly triggering an alert).', null=True), + ), + migrations.AlterField( + model_name='statuscheck', + name='verify_ssl_certificate', + field=models.BooleanField(default=True, help_text='Set to false to allow not try to verify ssl certificates (default True)'), + ), + migrations.AlterField( + model_name='userprofile', + name='hipchat_alias', + field=models.CharField(blank=True, default='', max_length=50), + ), + migrations.AlterField( + model_name='userprofile', + name='mobile_number', + field=models.CharField(blank=True, default='', max_length=20), + ), + ] diff --git a/cabot/cabotapp/models/base.py b/cabot/cabotapp/models/base.py index 2e46d5b7b..dd54c15b8 100644 --- a/cabot/cabotapp/models/base.py +++ b/cabot/cabotapp/models/base.py @@ -388,14 +388,14 @@ class Meta: class ServiceStatusSnapshot(Snapshot): - service = models.ForeignKey(Service, related_name='snapshots') + service = models.ForeignKey(Service, related_name='snapshots', on_delete=models.CASCADE) def __unicode__(self): return u"%s: %s" % (self.service.name, self.overall_status) class InstanceStatusSnapshot(Snapshot): - instance = models.ForeignKey(Instance, related_name='snapshots') + instance = models.ForeignKey(Instance, related_name='snapshots', on_delete=models.CASCADE) def __unicode__(self): return u"%s: %s" % (self.instance.name, self.overall_status) @@ -436,7 +436,7 @@ class StatusCheck(PolymorphicModel): help_text='Number of successive failures permitted before check will be marked as failed. Default is 0, ' 'i.e. fail on first failure.' ) - created_by = models.ForeignKey(User, null=True) + created_by = models.ForeignKey(User, null=True, on_delete=models.CASCADE) calculated_status = models.CharField( max_length=50, choices=Service.STATUSES, default=Service.CALCULATED_PASSING_STATUS, blank=True) last_run = models.DateTimeField(null=True) @@ -804,7 +804,7 @@ class StatusCheckResult(models.Model): Checks don't have to use all the fields, so most should be nullable """ - status_check = models.ForeignKey(StatusCheck) + status_check = models.ForeignKey(StatusCheck, on_delete=models.CASCADE) time = models.DateTimeField(null=False, db_index=True) time_complete = models.DateTimeField(null=True, db_index=True) raw_data = models.TextField(null=True) @@ -858,14 +858,15 @@ def save(self, *args, **kwargs): class AlertAcknowledgement(models.Model): time = models.DateTimeField() - user = models.ForeignKey(settings.AUTH_USER_MODEL) - service = models.ForeignKey(Service) + user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) + service = models.ForeignKey(Service, on_delete=models.CASCADE) cancelled_time = models.DateTimeField(null=True, blank=True) cancelled_user = models.ForeignKey( settings.AUTH_USER_MODEL, null=True, blank=True, - related_name='cancelleduser_set' + related_name='cancelleduser_set', + on_delete=models.CASCADE, ) def unexpired(self): @@ -876,7 +877,7 @@ def expires(self): class UserProfile(models.Model): - user = models.OneToOneField(settings.AUTH_USER_MODEL, related_name='profile') + user = models.OneToOneField(settings.AUTH_USER_MODEL, related_name='profile', on_delete=models.CASCADE) def user_data(self): for user_data_subclass in AlertPluginUserData.__subclasses__(): @@ -911,7 +912,7 @@ def create_user_profile(sender, instance, created, **kwargs): class Shift(models.Model): start = models.DateTimeField() end = models.DateTimeField() - user = models.ForeignKey(settings.AUTH_USER_MODEL) + user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) uid = models.TextField() last_modified = models.DateTimeField() deleted = models.BooleanField(default=False) diff --git a/cabot/cabotapp/models/jenkins_check_plugin.py b/cabot/cabotapp/models/jenkins_check_plugin.py index 32a216df9..23d722efb 100644 --- a/cabot/cabotapp/models/jenkins_check_plugin.py +++ b/cabot/cabotapp/models/jenkins_check_plugin.py @@ -7,7 +7,7 @@ class JenkinsStatusCheck(StatusCheck): - jenkins_config = models.ForeignKey('JenkinsConfig') + jenkins_config = models.ForeignKey('JenkinsConfig', on_delete=models.CASCADE) @property def check_category(self): diff --git a/cabot/cabotapp/tests/test_urlprefix.py b/cabot/cabotapp/tests/test_urlprefix.py index 34ca80928..45bc2a4af 100644 --- a/cabot/cabotapp/tests/test_urlprefix.py +++ b/cabot/cabotapp/tests/test_urlprefix.py @@ -1,6 +1,6 @@ import sys -from django.core.urlresolvers import reverse, clear_url_caches +from django.urls import reverse, clear_url_caches from django.conf import settings from django.test.utils import override_settings from importlib import import_module diff --git a/cabot/cabotapp/tests/tests_basic.py b/cabot/cabotapp/tests/tests_basic.py index 252aa61da..bce5d0cb3 100644 --- a/cabot/cabotapp/tests/tests_basic.py +++ b/cabot/cabotapp/tests/tests_basic.py @@ -21,7 +21,7 @@ from django.contrib.auth.models import Permission from django.contrib.auth.models import User from django.core import mail -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test.client import Client from django.test.utils import override_settings from django.test import TestCase diff --git a/cabot/cabotapp/views.py b/cabot/cabotapp/views.py index 1b8c16113..417fb8114 100644 --- a/cabot/cabotapp/views.py +++ b/cabot/cabotapp/views.py @@ -1,10 +1,10 @@ import json import re from datetime import date, datetime, timedelta -from itertools import dropwhile, groupby, izip_longest +from itertools import dropwhile, groupby, zip_longest import requests -from alert import AlertPlugin, AlertPluginUserData +from .alert import AlertPlugin, AlertPluginUserData from cabot.cabotapp import alert from cabot.cabotapp.utils import cabot_needs_setup from dateutil.relativedelta import relativedelta @@ -16,7 +16,7 @@ from django.contrib.auth.models import User from django.core.exceptions import ValidationError from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger -from django.core.urlresolvers import reverse, reverse_lazy +from django.urls import reverse, reverse_lazy from django.core.validators import URLValidator from django.db import transaction from django.db.models.functions import Lower @@ -28,13 +28,13 @@ from django.utils.timezone import utc from django.views.generic import (CreateView, DeleteView, DetailView, ListView, TemplateView, UpdateView, View) -from models import (GraphiteStatusCheck, HttpStatusCheck, ICMPStatusCheck, +from .models import (GraphiteStatusCheck, HttpStatusCheck, ICMPStatusCheck, Instance, JenkinsStatusCheck, Service, Shift, StatusCheck, StatusCheckResult, UserProfile, get_custom_check_plugins, get_duty_officers) from rest_framework.views import APIView from rest_framework.response import Response -from tasks import run_status_check as _run_status_check +from .tasks import run_status_check as _run_status_check from .graphite import get_data, get_matching_metrics @@ -438,7 +438,7 @@ def get_report(self): ).order_by('time') groups = dropwhile(lambda item: item[0], groupby(results, key=lambda r: r.succeeded)) times = [next(group).time for succeeded, group in groups] - pairs = izip_longest(*([iter(times)] * 2)) + pairs = zip_longest(*([iter(times)] * 2)) check.problems = [(start, end, (end or now) - start) for start, end in pairs] if results: check.success_rate = results.filter(succeeded=True).count() / float(len(results)) * 100 @@ -1110,12 +1110,12 @@ def graphite_api_data(request): matching_metrics = None try: data = get_data(metric, mins_to_check) - except requests.exceptions.RequestException, e: + except requests.exceptions.RequestException as e: pass if not data: try: matching_metrics = get_matching_metrics(metric) - except requests.exceptions.RequestException, e: + except requests.exceptions.RequestException as e: return jsonify({'status': 'error', 'message': str(e)}) matching_metrics = {'metrics': matching_metrics} return jsonify({'status': 'ok', 'data': data, 'matchingMetrics': matching_metrics}) diff --git a/cabot/settings.py b/cabot/settings.py index 187860113..d615d1e05 100644 --- a/cabot/settings.py +++ b/cabot/settings.py @@ -2,14 +2,14 @@ import dj_database_url import re from django.conf import settings -from django.core.urlresolvers import reverse_lazy +from django.urls import reverse_lazy from cabot.settings_utils import environ_get_list, force_bool from cabot.cabot_config import * settings_dir = os.path.dirname(__file__) PROJECT_ROOT = os.path.abspath(settings_dir) -DEBUG = force_bool(os.environ.get('DEBUG', False)) +DEBUG = force_bool(os.environ.get('DEBUG', True)) ADMINS = ( ('Admin', os.environ.get('ADMIN_EMAIL', 'name@example.com')), @@ -20,7 +20,18 @@ if os.environ.get('CABOT_FROM_EMAIL'): DEFAULT_FROM_EMAIL = os.environ['CABOT_FROM_EMAIL'] -DATABASES = {'default': dj_database_url.config()} +#DATABASES = {'default': dj_database_url.config()} + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.postgresql_psycopg2', + 'NAME': 'cabot', + 'USER': 'root', + 'PASSWORD': 'root', + 'HOST': 'localhost', + 'PORT': '5432', + } +} TEST_RUNNER = 'django.test.runner.DiscoverRunner' @@ -118,14 +129,16 @@ }, }] -MIDDLEWARE_CLASSES = ( - 'whitenoise.middleware.WhiteNoiseMiddleware', - 'django.middleware.common.CommonMiddleware', +MIDDLEWARE = ( + + + 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', ) ROOT_URLCONF = 'cabot.urls' @@ -162,10 +175,10 @@ INSTALLED_APPS += tuple(CABOT_PLUGINS_ENABLED_PARSED) COMPRESS_PRECOMPILERS = ( - ('text/coffeescript', 'coffee --compile --stdio'), + ('text/coffeescript', 'coffeecompressorcompiler.filter.CoffeeScriptCompiler'), ('text/eco', 'eco -i TEMPLATES {infile} && cat "$(echo "{infile}" | sed -e "s/\.eco$/.js/g")"'), - ('text/less', 'lessc {infile} > {outfile}'), + ('text/less', '/usr/bin/less {infile} > {outfile}'), ) # For the email settings we both accept old and new names diff --git a/cabot/templates/base_public.html b/cabot/templates/base_public.html index 61e22a356..c15d18c55 100644 --- a/cabot/templates/base_public.html +++ b/cabot/templates/base_public.html @@ -1,4 +1,4 @@ -{% load static from staticfiles %} +{% load static %} diff --git a/cabot/templates/cabotapp/about.html b/cabot/templates/cabotapp/about.html index 9b286a23f..00ef2f7da 100644 --- a/cabot/templates/cabotapp/about.html +++ b/cabot/templates/cabotapp/about.html @@ -1,5 +1,5 @@ {% extends 'base_public.html' %} -{% load static from staticfiles %} +{% load static %} {% block title %}{{ block.super }} - About{% endblock title %} {% block content %} diff --git a/cabot/templates/cabotapp/instance_detail.html b/cabot/templates/cabotapp/instance_detail.html index f3a4e1a42..fdce7947e 100644 --- a/cabot/templates/cabotapp/instance_detail.html +++ b/cabot/templates/cabotapp/instance_detail.html @@ -1,5 +1,5 @@ {% extends 'base.html' %} -{% load static from staticfiles %} +{% load static %} {% block title %}{{ block.super }} - {{ instance.name }}{% endblock title %} {% block content %} diff --git a/cabot/templates/cabotapp/service_detail.html b/cabot/templates/cabotapp/service_detail.html index 4c15d389a..ab2822e8c 100644 --- a/cabot/templates/cabotapp/service_detail.html +++ b/cabot/templates/cabotapp/service_detail.html @@ -1,6 +1,6 @@ {% extends 'base.html' %} {% load extra %} -{% load static from staticfiles %} +{% load static %} {% block title %}{{ block.super }} - {{ service.name }}{% endblock title %} diff --git a/cabot/templates/cabotapp/statuscheck_form.html b/cabot/templates/cabotapp/statuscheck_form.html index aad13b873..94262b045 100644 --- a/cabot/templates/cabotapp/statuscheck_form.html +++ b/cabot/templates/cabotapp/statuscheck_form.html @@ -1,5 +1,5 @@ {% extends 'base.html' %} -{% load static from staticfiles %} +{% load static %} {% block content %}
diff --git a/cabot/templates/cabotapp/statuscheckresult_detail.html b/cabot/templates/cabotapp/statuscheckresult_detail.html index 492b9ba85..22ac63a89 100644 --- a/cabot/templates/cabotapp/statuscheckresult_detail.html +++ b/cabot/templates/cabotapp/statuscheckresult_detail.html @@ -1,5 +1,5 @@ {% extends 'base.html' %} -{% load static from staticfiles %} +{% load static %} {% block content %}
diff --git a/cabot/urls.py b/cabot/urls.py index 3333857b0..e524edbe4 100644 --- a/cabot/urls.py +++ b/cabot/urls.py @@ -27,7 +27,7 @@ from django.views.generic.base import RedirectView from django.views.static import serve from django.shortcuts import redirect -from django.contrib.auth.views import login, logout, password_reset, password_reset_done, password_reset_confirm +from django.contrib.auth.views import LoginView, LogoutView, PasswordResetView, PasswordResetDoneView, PasswordResetConfirmView admin.autodiscover() from importlib import import_module @@ -64,15 +64,15 @@ def home_authentication_switcher(request, *args, **kwargs): name='dashboard'), url(r'^subscriptions/', view=subscriptions, name='subscriptions'), - url(r'^accounts/login/', view=first_time_setup_wrapper(login), name='login'), - url(r'^accounts/logout/', view=logout, name='logout'), + url(r'^accounts/login/', view=first_time_setup_wrapper(LoginView), name='login'), + url(r'^accounts/logout/', view=LogoutView, name='logout'), url(r'^setup/', view=SetupView.as_view(), name='first_time_setup'), url(r'^accounts/password-reset/', - view=password_reset, name='password-reset'), + view=PasswordResetView, name='password-reset'), url(r'^accounts/password-reset-done/', - view=password_reset_done, name='password-reset-done'), + view=PasswordResetDoneView, name='password-reset-done'), url(r'^accounts/password-reset-confirm/', - view=password_reset_confirm, name='password-reset-confirm'), + view=PasswordResetConfirmView, name='password-reset-confirm'), url(r'^status/', view=checks_run_recently, name='system-status'), url(r'^about/', view=about, @@ -163,7 +163,8 @@ def home_authentication_switcher(request, *args, **kwargs): view=PluginSettingsView.as_view(), name='plugin-settings'), url(r'^user/(?P\d+)/profile/(?P.+)/', view=UserProfileUpdateAlert.as_view(), name='update-alert-user-data'), - url(r'^admin/', include(admin.site.urls)), + #url(r'^admin/', include(admin.site.urls)), + url(r'^admin/', admin.site.urls), # Comment below line to disable browsable rest api url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')), url(r'^api/', include(rest_urls.router.urls)), diff --git a/cabot/version.py b/cabot/version.py index e96abf816..de6eebbc0 100644 --- a/cabot/version.py +++ b/cabot/version.py @@ -1,5 +1,5 @@ try: import pkg_resources version = pkg_resources.require("cabot")[0].version -except Exception, ImportError: +except Exception(ImportError): version = 'unknown' diff --git a/conf/default.env b/conf/default.env index fd289b60d..7bed20454 100644 --- a/conf/default.env +++ b/conf/default.env @@ -1,5 +1,5 @@ # Plugins to be loaded at launch -CABOT_PLUGINS_ENABLED=cabot_alert_hipchat,cabot_alert_twilio,cabot_alert_email,cabot_alert_slack +#CABOT_PLUGINS_ENABLED=cabot_alert_hipchat,cabot_alert_twilio,cabot_alert_email,cabot_alert_slack DEBUG=t DATABASE_URL=postgres://postgres@db:5432/postgres diff --git a/docker-compose.yml b/docker-compose.yml index f496277d5..255c72fa8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -49,5 +49,6 @@ services: volumes: - datavolume:/var/lib/postgresql/data + volumes: datavolume: diff --git a/requiements.txt b/requiements.txt new file mode 100644 index 000000000..a4e44ae1d --- /dev/null +++ b/requiements.txt @@ -0,0 +1,111 @@ +amqp==2.6.1 +anyjson==0.3.3 +appdirs==1.4.4 +asgiref==3.4.1 +backcall==0.2.0 +billiard==3.6.4.0 +boto==2.49.0 +boto3==1.17.106 +botocore==1.20.106 +cabot-alert-email==1.4.3 +cabot-alert-hipchat==2.0.3 +cabot-alert-slack==0.8.3 +cabot-alert-twilio==1.3.3 +cached-property==1.5.2 +celery==4.4.2 +certifi==2021.5.30 +cffi==1.14.5 +chardet==4.0.0 +click==7.1.2 +click-didyoumean==0.0.3 +click-plugins==1.1.1 +click-repl==0.2.0 +coffee-compressor-compiler==0.2.0 +coreapi==2.3.3 +coreschema==0.0.4 +coverage==5.5 +cryptography==3.4.7 +decorator==5.0.9 +defusedxml==0.7.1 +dj-database-url==0.5.0 +Django==3.2.5 +django-appconf==1.0.4 +django-auth-ldap==2.4.0 +django-autocomplete-light==3.8.2 +django-bootstrap-form==3.4 +django-compressor==2.4.1 +django-coverage-plugin==2.0.0 +django-filter==2.4.0 +django-jsonify==0.3.0 +django-polymorphic==3.0.0 +djangorestframework==3.12.4 +docutils==0.17.1 +freezegun==1.1.0 +futures==3.1.1 +gevent==21.1.2 +greenlet==1.1.0 +gunicorn==20.1.0 +httplib2==0.19.1 +icalendar==4.0.7 +idna==2.10 +importlib-metadata==4.6.1 +ipdb==0.13.9 +ipython==7.16.1 +ipython-genutils==0.2.0 +isort==5.9.1 +itypes==1.2.0 +jedi==0.18.0 +Jinja2==3.0.1 +jmespath==0.10.0 +kombu==4.6.11 +Markdown==3.3.4 +MarkupSafe==2.0.1 +mock==4.0.3 +multi-key-dict==2.0.3 +oauthlib==3.1.1 +packaging==21.0 +parso==0.8.2 +pbr==5.6.0 +pexpect==4.8.0 +pickleshare==0.7.5 +prompt-toolkit==3.0.19 +psycopg2==2.7.7 +psycopg2-binary==2.9.1 +ptyprocess==0.7.0 +pyasn1==0.4.8 +pyasn1-modules==0.2.8 +pycparser==2.20 +pycurl==7.43.0.6 +PyExecJS==1.5.1 +Pygments==2.9.0 +PyJWT==2.1.0 +pyparsing==2.4.7 +PySocks==1.7.1 +python-dateutil==2.8.1 +python-jenkins==1.7.0 +python-ldap==3.3.1 +python-openid==2.2.5 +python3-openid==3.2.0 +pytz==2021.1 +rcssmin==1.0.6 +redis==3.5.3 +requests==2.25.1 +requests-oauthlib==1.3.0 +rjsmin==1.1.0 +s3transfer==0.4.2 +six==1.16.0 +social-auth-app-django==4.0.0 +social-auth-core==4.1.0 +sqlparse==0.4.1 +toml==0.10.2 +traitlets==4.3.3 +twilio==6.50.1 +typing-extensions==3.10.0.0 +uritemplate==3.0.1 +urllib3==1.26.6 +vine==1.3.0 +wcwidth==0.2.5 +whitenoise==5.2.0 +zipp==3.5.0 +zope.event==4.5.0 +zope.interface==5.4.0 From 7719e0c0534804c9f35e3b24a9e494707170d7d3 Mon Sep 17 00:00:00 2001 From: Tomas Date: Thu, 8 Jul 2021 12:47:08 -0300 Subject: [PATCH 02/24] resuelto el tema login --- cabot/cabotapp/views.py | 4 +++- cabot/urls.py | 18 ++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/cabot/cabotapp/views.py b/cabot/cabotapp/views.py index 417fb8114..51635fd81 100644 --- a/cabot/cabotapp/views.py +++ b/cabot/cabotapp/views.py @@ -901,10 +901,12 @@ def get_context_data(self, **kwargs): return context + class InstanceCreateView(LoginRequiredMixin, CommonCreateView): model = Instance form_class = InstanceForm + def form_valid(self, form): ret = super(InstanceCreateView, self).form_valid(form) if self.object.status_checks.filter(polymorphic_ctype__model='icmpstatuscheck').count() == 0: @@ -940,7 +942,7 @@ def get_initial(self): pass return initial - + @login_required def acknowledge_alert(request, pk): diff --git a/cabot/urls.py b/cabot/urls.py index e524edbe4..477405e1f 100644 --- a/cabot/urls.py +++ b/cabot/urls.py @@ -1,5 +1,7 @@ from django.conf.urls import include, url +from django.urls import path from django.conf import settings +from requests.api import request from cabot.cabotapp.views import ( about, run_status_check, graphite_api_data, checks_run_recently, duplicate_icmp_check, duplicate_graphite_check, duplicate_http_check, duplicate_jenkins_check, @@ -37,12 +39,12 @@ logger = logging.getLogger(__name__) def first_time_setup_wrapper(func): - def wrapper(*args, **kwargs): - if cabot_needs_setup(): + def wrapper(request, *args, **kwargs): + if cabot_needs_setup(): return redirect('first_time_setup') - else: - return func(*args, **kwargs) - return wrapper + else: + return func.as_view(request, *args, **kwargs) + return wrapper def home_authentication_switcher(request, *args, **kwargs): @@ -64,8 +66,8 @@ def home_authentication_switcher(request, *args, **kwargs): name='dashboard'), url(r'^subscriptions/', view=subscriptions, name='subscriptions'), - url(r'^accounts/login/', view=first_time_setup_wrapper(LoginView), name='login'), - url(r'^accounts/logout/', view=LogoutView, name='logout'), + url(r'^accounts/login/', view=LoginView.as_view(), name='login'), + url(r'^accounts/logout/', LogoutView.as_view(), name='logout'), url(r'^setup/', view=SetupView.as_view(), name='first_time_setup'), url(r'^accounts/password-reset/', view=PasswordResetView, name='password-reset'), @@ -97,7 +99,7 @@ def home_authentication_switcher(request, *args, **kwargs): url(r'^instances/', view=InstanceListView.as_view(), name='instances'), - url(r'^instance/create/', view=InstanceCreateView.as_view(), + url(r'^instance/create/', InstanceCreateView.as_view(), name='create-instance'), url(r'^instance/update/(?P\d+)/', view=InstanceUpdateView.as_view(), name='update-instance'), From 5b4957b68a6bc6f55bc33b1988e747ae2ba55a2b Mon Sep 17 00:00:00 2001 From: Ladrusca Date: Tue, 20 Jul 2021 15:14:26 -0300 Subject: [PATCH 03/24] completamente modularizada --- Dockerfile | 51 +- cabot/cabot_config.py | 4 +- cabot/cabotapp/admin.py | 10 +- cabot/cabotapp/alert.py | 7 + cabot/cabotapp/apps.py | 3 +- .../{graphite.py => graphite_delete.py} | 0 .../{jenkins.py => jenkins_delete.py} | 0 cabot/cabotapp/migrations/0001_initial.py | 11 +- .../migrations/0008_auto_20210707_1645.py | 4 - .../migrations/0009_auto_20210719_2116.py | 30 + .../migrations/0010_auto_20210720_1338.py | 33 ++ cabot/cabotapp/models/__init__.py | 3 +- cabot/cabotapp/models/base.py | 484 ++++++---------- cabot/cabotapp/plugins_a_borrar/__init__.py | 4 + .../graphite_status_check_delete.py | 146 +++++ .../icmp_status_check_delete.py | 54 ++ .../jenkins_check_plugin_delete.py} | 42 +- cabot/cabotapp/plugins_a_borrar/urls_general | 21 + .../cabotapp/plugins_a_borrar/views_delete.py | 17 + cabot/cabotapp/tasks.py | 32 +- cabot/cabotapp/views.py | 210 +------ cabot/celery.py | 14 +- cabot/celeryconfig.py | 11 - cabot/config.py | 31 ++ cabot/rest_urls.py | 13 +- cabot/settings.py | 44 +- cabot/settings_utils.py | 9 +- cabot/static/arachnys/css/base.less | 55 -- cabot/templates/base.html | 13 +- cabot/templates/base_public.html | 49 +- .../templates/cabotapp/_statuscheck_list.html | 13 +- .../cabotapp/alertpluginuserdata_form.html | 2 +- .../cabotapp/instance_confirm_delete.html | 2 +- cabot/templates/cabotapp/instance_detail.html | 161 +++--- cabot/templates/cabotapp/instance_form.html | 2 +- cabot/templates/cabotapp/instance_list.html | 2 +- .../cabotapp/plugin_settings_form.html | 41 +- .../cabotapp/service_confirm_delete.html | 2 +- cabot/templates/cabotapp/service_detail.html | 153 ++--- cabot/templates/cabotapp/service_form.html | 2 +- cabot/templates/cabotapp/service_list.html | 26 +- cabot/templates/cabotapp/shift_list.html | 2 +- .../cabotapp/statuscheck_confirm_delete.html | 2 +- .../cabotapp/statuscheck_detail.html | 2 +- .../templates/cabotapp/statuscheck_form.html | 203 ++++--- .../templates/cabotapp/statuscheck_list.html | 24 +- .../cabotapp/statuscheckresult_detail.html | 60 +- cabot/urls.py | 47 +- conf/default.env | 2 +- deprecated!/.coveragerc | 6 + deprecated!/.foreman | 4 + deprecated!/CHANGES | 272 +++++++++ "deprecated!/Documento sin t\303\255tulo" | 35 ++ deprecated!/MANIFEST.in | 6 + deprecated!/Pipfile | 30 + deprecated!/Procfile | 3 + deprecated!/Procfile.dev | 3 + deprecated!/Vagrantfile | 50 ++ deprecated!/celerybeat-schedule.bak | 4 + deprecated!/celerybeat-schedule.dat | Bin 0 -> 3728 bytes deprecated!/celerybeat-schedule.dir | 4 + deprecated!/docker-compose-base.yml | 10 + deprecated!/docker-compose-test.yml | 13 + deprecated!/docker-compose.yml | 72 +++ deprecated!/example_local_config.yml | 13 + deprecated!/get-docker.sh | 525 ++++++++++++++++++ deprecated!/gunicorn.conf | 7 + deprecated!/makemigrations | 4 + deprecated!/setup.cfg | 7 + deprecated!/setup_dev.sh | 3 + deprecated!/upstart/process.conf.erb | 6 + manage.py | 8 + requirements-dev.txt | 12 +- requirements-plugins.txt | 9 +- requirements.txt | 177 ++++-- tox.ini | 2 +- 76 files changed, 2359 insertions(+), 1079 deletions(-) rename cabot/cabotapp/{graphite.py => graphite_delete.py} (100%) rename cabot/cabotapp/{jenkins.py => jenkins_delete.py} (100%) create mode 100644 cabot/cabotapp/migrations/0009_auto_20210719_2116.py create mode 100644 cabot/cabotapp/migrations/0010_auto_20210720_1338.py create mode 100644 cabot/cabotapp/plugins_a_borrar/__init__.py create mode 100644 cabot/cabotapp/plugins_a_borrar/graphite_status_check_delete.py create mode 100644 cabot/cabotapp/plugins_a_borrar/icmp_status_check_delete.py rename cabot/cabotapp/{models/jenkins_check_plugin.py => plugins_a_borrar/jenkins_check_plugin_delete.py} (79%) create mode 100644 cabot/cabotapp/plugins_a_borrar/urls_general create mode 100644 cabot/cabotapp/plugins_a_borrar/views_delete.py delete mode 100644 cabot/celeryconfig.py create mode 100644 cabot/config.py delete mode 100644 cabot/static/arachnys/css/base.less create mode 100644 deprecated!/.coveragerc create mode 100644 deprecated!/.foreman create mode 100644 deprecated!/CHANGES create mode 100644 "deprecated!/Documento sin t\303\255tulo" create mode 100644 deprecated!/MANIFEST.in create mode 100644 deprecated!/Pipfile create mode 100644 deprecated!/Procfile create mode 100644 deprecated!/Procfile.dev create mode 100644 deprecated!/Vagrantfile create mode 100644 deprecated!/celerybeat-schedule.bak create mode 100644 deprecated!/celerybeat-schedule.dat create mode 100644 deprecated!/celerybeat-schedule.dir create mode 100644 deprecated!/docker-compose-base.yml create mode 100644 deprecated!/docker-compose-test.yml create mode 100644 deprecated!/docker-compose.yml create mode 100644 deprecated!/example_local_config.yml create mode 100644 deprecated!/get-docker.sh create mode 100644 deprecated!/gunicorn.conf create mode 100755 deprecated!/makemigrations create mode 100644 deprecated!/setup.cfg create mode 100755 deprecated!/setup_dev.sh create mode 100644 deprecated!/upstart/process.conf.erb diff --git a/Dockerfile b/Dockerfile index f42761fb1..3feeacd52 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,33 +1,34 @@ -FROM node:4-alpine +FROM python:3.6.5-jessie + +RUN apt-get update +RUN DEBIAN_FRONTEND=noninteractive apt-get install -y \ + default-libmysqlclient-dev \ + build-essential \ + python3-dev \ + python2.7-dev \ + libldap2-dev \ + libsasl2-dev \ + slapd \ + ldap-utils \ + python-tox \ + lcov \ + valgrind\ + curl\ + python-dev \ + gcc \ + musl-dev \ + libffi-dev \ + ca-certificates \ + bash ENV PYTHONUNBUFFERED 1 +RUN pip install --upgrade pip + RUN mkdir /code WORKDIR /code -RUN apk add --no-cache \ - python-dev \ - py-pip \ - postgresql-dev \ - gcc \ - curl \ - curl-dev \ - libcurl \ - musl-dev \ - libffi-dev \ - openldap-dev \ - ca-certificates \ - bash - -RUN npm config set unsafe-perm true -RUN npm install -g \ - --registry http://registry.npmjs.org/ \ - coffee-script \ - less@1.3 - -RUN pip install --upgrade pip - COPY requirements.txt ./ RUN pip install --no-cache-dir -r requirements.txt @@ -39,4 +40,6 @@ RUN pip install --no-cache-dir -r requirements-plugins.txt ADD . /code/ -ENTRYPOINT ["./docker-entrypoint.sh"] + + +ENTRYPOINT ["./docker-entrypoint.sh"] \ No newline at end of file diff --git a/cabot/cabot_config.py b/cabot/cabot_config.py index 2a90c7b38..c82754e8b 100644 --- a/cabot/cabot_config.py +++ b/cabot/cabot_config.py @@ -21,7 +21,7 @@ HTTP_USER_AGENT = os.environ.get('HTTP_USER_AGENT', 'Cabot') # How often should alerts be sent for important failures? -ALERT_INTERVAL = int(os.environ.get('ALERT_INTERVAL', 10)) +ALERT_INTERVAL = int(os.environ.get('ALERT_INTERVAL', 1)) # How often should notifications be sent for less important issues? NOTIFICATION_INTERVAL = int(os.environ.get('NOTIFICATION_INTERVAL', 120)) @@ -31,4 +31,4 @@ # Default plugins are used if the user has not specified. #CABOT_PLUGINS_ENABLED = os.environ.get('CABOT_PLUGINS_ENABLED', 'cabot_alert_hipchat,cabot_alert_twilio,cabot_alert_email') -CABOT_PLUGINS_ENABLED = os.environ.get('CABOT_PLUGINS_ENABLED', 'cabot_alert_email') \ No newline at end of file +CABOT_PLUGINS_ENABLED = os.environ.get('CABOT_PLUGINS_ENABLED') \ No newline at end of file diff --git a/cabot/cabotapp/admin.py b/cabot/cabotapp/admin.py index a48581d09..ca1d1d381 100644 --- a/cabot/cabotapp/admin.py +++ b/cabot/cabotapp/admin.py @@ -3,10 +3,13 @@ PolymorphicParentModelAdmin) from .alert import AlertPlugin, AlertPluginUserData -from .models import (AlertAcknowledgement, Instance, JenkinsConfig, Service, - ServiceStatusSnapshot, Shift, StatusCheck, - StatusCheckResult, UserProfile) +from .models.base import (AlertAcknowledgement, Instance, Service, + ServiceStatusSnapshot, Shift,UserProfile, + StatusCheckResult,StatusCheck + ) + +#from .plugins.jenkins_check_plugin import (JenkinsConfig) class StatusCheckAdmin(PolymorphicParentModelAdmin): base_model = StatusCheck @@ -30,4 +33,3 @@ class ChildStatusCheckAdmin(PolymorphicChildModelAdmin): admin.site.register(AlertPlugin) admin.site.register(AlertPluginUserData) admin.site.register(AlertAcknowledgement) -admin.site.register(JenkinsConfig) diff --git a/cabot/cabotapp/alert.py b/cabot/cabotapp/alert.py index 245672258..f1e2e37ee 100644 --- a/cabot/cabotapp/alert.py +++ b/cabot/cabotapp/alert.py @@ -38,6 +38,10 @@ def send_alert(self, service, users, duty_officers): return True + def __str__(self): + return self.name + + class AlertPluginUserData(PolymorphicModel): title = models.CharField(max_length=30, editable=False) user = models.ForeignKey('UserProfile', editable=False , on_delete=models.CASCADE) @@ -51,6 +55,9 @@ def __unicode__(self): def serialize(self): return {} + def __str__(self): + return self.name + def send_alert(service, duty_officers=None): users = service.users_to_notify.filter(is_active=True) diff --git a/cabot/cabotapp/apps.py b/cabot/cabotapp/apps.py index 0b27096f3..a5853555c 100644 --- a/cabot/cabotapp/apps.py +++ b/cabot/cabotapp/apps.py @@ -4,9 +4,8 @@ def post_migrate_callback(**kwargs): from cabot.cabotapp.alert import update_alert_plugins - from cabot.cabotapp.models import create_default_jenkins_config update_alert_plugins() - create_default_jenkins_config() + class CabotappConfig(AppConfig): name = 'cabot.cabotapp' diff --git a/cabot/cabotapp/graphite.py b/cabot/cabotapp/graphite_delete.py similarity index 100% rename from cabot/cabotapp/graphite.py rename to cabot/cabotapp/graphite_delete.py diff --git a/cabot/cabotapp/jenkins.py b/cabot/cabotapp/jenkins_delete.py similarity index 100% rename from cabot/cabotapp/jenkins.py rename to cabot/cabotapp/jenkins_delete.py diff --git a/cabot/cabotapp/migrations/0001_initial.py b/cabot/cabotapp/migrations/0001_initial.py index 28e84dadb..c584e81eb 100644 --- a/cabot/cabotapp/migrations/0001_initial.py +++ b/cabot/cabotapp/migrations/0001_initial.py @@ -269,16 +269,7 @@ class Migration(migrations.Migration): }, bases=('cabotapp.statuscheck',), ), - migrations.CreateModel( - name='HttpStatusCheck', - fields=[ - ], - options={ - 'abstract': False, - 'proxy': True, - }, - bases=('cabotapp.statuscheck',), - ), + migrations.CreateModel( name='ICMPStatusCheck', fields=[ diff --git a/cabot/cabotapp/migrations/0008_auto_20210707_1645.py b/cabot/cabotapp/migrations/0008_auto_20210707_1645.py index 42d509b0a..df5ca84d7 100644 --- a/cabot/cabotapp/migrations/0008_auto_20210707_1645.py +++ b/cabot/cabotapp/migrations/0008_auto_20210707_1645.py @@ -21,10 +21,6 @@ class Migration(migrations.Migration): name='graphitestatuscheck', options={'base_manager_name': 'objects'}, ), - migrations.AlterModelOptions( - name='httpstatuscheck', - options={'base_manager_name': 'objects'}, - ), migrations.AlterModelOptions( name='icmpstatuscheck', options={'base_manager_name': 'objects'}, diff --git a/cabot/cabotapp/migrations/0009_auto_20210719_2116.py b/cabot/cabotapp/migrations/0009_auto_20210719_2116.py new file mode 100644 index 000000000..2de644e5a --- /dev/null +++ b/cabot/cabotapp/migrations/0009_auto_20210719_2116.py @@ -0,0 +1,30 @@ +# Generated by Django 3.2.5 on 2021-07-20 00:16 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('cabot_check_http', '0002_auto_20210719_2116'), + ('cabotapp', '0008_auto_20210707_1645'), + ] + + operations = [ + migrations.AlterField( + model_name='Service', + name='status_checks', + field=models.ManyToManyField(blank=True, help_text='Checks used to calculate service status.', to='cabotapp.StatusCheck'), + ), + migrations.AlterField( + model_name='Instance', + name='status_checks', + field=models.ManyToManyField(blank=True, help_text='Checks used to calculate service status.', to='cabotapp.StatusCheck'), + ), + migrations.AlterField( + model_name='StatusCheckResult', + name='status_check', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cabotapp.statuscheck'), + ), + ] diff --git a/cabot/cabotapp/migrations/0010_auto_20210720_1338.py b/cabot/cabotapp/migrations/0010_auto_20210720_1338.py new file mode 100644 index 000000000..00e9cd47e --- /dev/null +++ b/cabot/cabotapp/migrations/0010_auto_20210720_1338.py @@ -0,0 +1,33 @@ +# Generated by Django 3.2.5 on 2021-07-20 16:38 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('cabotapp', '0009_auto_20210719_2116'), + ] + + operations = [ + migrations.RemoveField( + model_name='jenkinsstatuscheck', + name='jenkins_config', + ), + migrations.RemoveField( + model_name='jenkinsstatuscheck', + name='statuscheck_ptr', + ), + migrations.DeleteModel( + name='GraphiteStatusCheck', + ), + migrations.DeleteModel( + name='ICMPStatusCheck', + ), + migrations.DeleteModel( + name='JenkinsConfig', + ), + migrations.DeleteModel( + name='JenkinsStatusCheck', + ), + ] diff --git a/cabot/cabotapp/models/__init__.py b/cabot/cabotapp/models/__init__.py index eaac010e6..773cfc466 100644 --- a/cabot/cabotapp/models/__init__.py +++ b/cabot/cabotapp/models/__init__.py @@ -1,2 +1 @@ -from .base import * -from .jenkins_check_plugin import * +from .base import * \ No newline at end of file diff --git a/cabot/cabotapp/models/base.py b/cabot/cabotapp/models/base.py index dd54c15b8..415cd562c 100644 --- a/cabot/cabotapp/models/base.py +++ b/cabot/cabotapp/models/base.py @@ -19,9 +19,9 @@ from ..alert import AlertPluginUserData, send_alert, send_alert_update from ..calendar import get_events -from ..graphite import parse_metric from ..tasks import update_instance, update_service + RAW_DATA_LIMIT = 5000 logger = get_task_logger(__name__) @@ -73,7 +73,6 @@ def get_custom_check_plugins(): # Checks that aren't using the plugin system legacy_checks = [ "JenkinsStatusCheck", - "HttpStatusCheck", "ICMPStatusCheck", "GraphiteStatusCheck", ] @@ -255,17 +254,20 @@ def recent_snapshots(self): def graphite_status_checks(self): return self.status_checks.filter(polymorphic_ctype__model='graphitestatuscheck') + ''' def http_status_checks(self): return self.status_checks.filter(polymorphic_ctype__model='httpstatuscheck') + def active_http_status_checks(self): + return self.http_status_checks().filter(active=True) + ''' def jenkins_status_checks(self): return self.status_checks.filter(polymorphic_ctype__model='jenkinsstatuscheck') def active_graphite_status_checks(self): return self.graphite_status_checks().filter(active=True) - def active_http_status_checks(self): - return self.http_status_checks().filter(active=True) + def active_jenkins_status_checks(self): return self.jenkins_status_checks().filter(active=True) @@ -283,6 +285,10 @@ def all_failing_checks(self): return self.active_status_checks().exclude(calculated_status=self.CALCULATED_PASSING_STATUS) + def __str__(self): + return self.name + + class Service(CheckGroupMixin): def update_status(self): self.old_overall_status = self.overall_status @@ -323,6 +329,8 @@ def update_status(self): class Meta: ordering = ['name'] + def __str__(self): + return self.name class Instance(CheckGroupMixin): def duplicate(self): @@ -375,6 +383,9 @@ def delete(self, *args, **kwargs): return super(Instance, self).delete(*args, **kwargs) + def __str__(self): + return self.name + class Snapshot(models.Model): class Meta: abstract = True @@ -401,6 +412,151 @@ def __unicode__(self): return u"%s: %s" % (self.instance.name, self.overall_status) + + +def minimize_targets(targets): + split = [target.split(".") for target in targets] + + prefix_nodes_in_common = 0 + for i, nodes in enumerate(itertools.izip(*split)): + if any(node != nodes[0] for node in nodes): + prefix_nodes_in_common = i + break + split = [nodes[prefix_nodes_in_common:] for nodes in split] + + suffix_nodes_in_common = 0 + for i, nodes in enumerate(reversed(zip(*split))): + if any(node != nodes[0] for node in nodes): + suffix_nodes_in_common = i + break + if suffix_nodes_in_common: + split = [nodes[:-suffix_nodes_in_common] for nodes in split] + + return [".".join(nodes) for nodes in split] + + + + +class AlertAcknowledgement(models.Model): + time = models.DateTimeField() + user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) + service = models.ForeignKey(Service, on_delete=models.CASCADE) + cancelled_time = models.DateTimeField(null=True, blank=True) + cancelled_user = models.ForeignKey( + settings.AUTH_USER_MODEL, + null=True, + blank=True, + related_name='cancelleduser_set', + on_delete=models.CASCADE, + ) + + def unexpired(self): + return self.expires() > timezone.now() + + def expires(self): + return self.time + timedelta(minutes=settings.ACKNOWLEDGEMENT_EXPIRY) + + def __str__(self): + return self.name + + +class UserProfile(models.Model): + user = models.OneToOneField(settings.AUTH_USER_MODEL, related_name='profile', on_delete=models.CASCADE) + + def user_data(self): + for user_data_subclass in AlertPluginUserData.__subclasses__(): + user_data = user_data_subclass.objects.get_or_create(user=self, title=user_data_subclass.name) + return AlertPluginUserData.objects.filter(user=self) + + def __unicode__(self): + return 'User profile: %s' % self.user.username + + def save(self, *args, **kwargs): + # Enforce uniqueness + if self.fallback_alert_user: + profiles = UserProfile.objects.exclude(id=self.id) + profiles.update(fallback_alert_user=False) + return super(UserProfile, self).save(*args, **kwargs) + + @property + def prefixed_mobile_number(self): + return '+%s' % self.mobile_number + + mobile_number = models.CharField(max_length=20, blank=True, default='') + hipchat_alias = models.CharField(max_length=50, blank=True, default='') + fallback_alert_user = models.BooleanField(default=False) + +def create_user_profile(sender, instance, created, **kwargs): + if created: + UserProfile.objects.create(user=instance) + +post_save.connect(create_user_profile, sender=settings.AUTH_USER_MODEL) + + +class Shift(models.Model): + start = models.DateTimeField() + end = models.DateTimeField() + user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) + uid = models.TextField() + last_modified = models.DateTimeField() + deleted = models.BooleanField(default=False) + + def __unicode__(self): + deleted = '' + if self.deleted: + deleted = ' (deleted)' + return "%s: %s to %s%s" % (self.user.username, self.start, self.end, deleted) + + def __str__(self): + return self.name + + +def get_duty_officers(at_time=None): + """Returns a list of duty officers for a given time or now if none given""" + duty_officers = [] + if not at_time: + at_time = timezone.now() + current_shifts = Shift.objects.filter( + deleted=False, + start__lt=at_time, + end__gt=at_time, + ) + if current_shifts: + duty_officers = [shift.user for shift in current_shifts] + return duty_officers + else: + try: + u = UserProfile.objects.get(fallback_alert_user=True) + return [u.user] + except UserProfile.DoesNotExist: + return [] + + +def update_shifts(): + events = get_events() + users = User.objects.filter(is_active=True) + user_lookup = {} + for u in users: + user_lookup[u.username.lower()] = u + future_shifts = Shift.objects.filter(start__gt=timezone.now()) + future_shifts.update(deleted=True) + + for event in events: + e = event['summary'].lower().strip() + if e in user_lookup: + user = user_lookup[e] + # Delete any events that have been updated in ical + Shift.objects.filter(uid=event['uid'], + last_modified__lt=event['last_modified']).delete() + Shift.objects.get_or_create( + uid=event['uid'], + start=event['start'], + end=event['end'], + last_modified=event['last_modified'], + user=user, + deleted=False) + + class StatusCheck(PolymorphicModel): """ Base class for polymorphic models. We're going to use @@ -539,8 +695,8 @@ def run(self): result.succeeded = False except Exception as e: result = StatusCheckResult(status_check=self) - logger.error(u"Error performing check: %s" % (e.message,)) - result.error = u'Error in performing check: %s' % (e.message,) + logger.error(u"Error performing check: %s" % (e)) + result.error = u'Error in performing check: %s' % (e) result.succeeded = False finish = timezone.now() result.time = start @@ -548,6 +704,7 @@ def run(self): result.save() self.last_run = finish self.save() + def _run(self): """ @@ -592,208 +749,18 @@ def duplicate(self, inst_set=(), serv_set=()): def update_related_services(self): services = self.service_set.all() for service in services: - update_service.delay(service.id) + update_service(service.id) + def update_related_instances(self): instances = self.instance_set.all() for instance in instances: - update_instance.delay(instance.id) - - -class ICMPStatusCheck(StatusCheck): - class Meta(StatusCheck.Meta): - proxy = True - - @property - def check_category(self): - return "ICMP/Ping Check" - - def _run(self): - result = StatusCheckResult(status_check=self) - instances = self.instance_set.all() - target = self.instance_set.get().address - - args = ['ping', '-c', '1', target] - try: - # We redirect stderr to STDOUT because ping can write to both, depending on the kind of error. - subprocess.check_output(args, stderr=subprocess.STDOUT, shell=False) - result.succeeded = True - except subprocess.CalledProcessError as e: - result.succeeded = False - result.error = e.output - - return result - + update_instance(instance.id) -def minimize_targets(targets): - split = [target.split(".") for target in targets] - - prefix_nodes_in_common = 0 - for i, nodes in enumerate(itertools.izip(*split)): - if any(node != nodes[0] for node in nodes): - prefix_nodes_in_common = i - break - split = [nodes[prefix_nodes_in_common:] for nodes in split] - - suffix_nodes_in_common = 0 - for i, nodes in enumerate(reversed(zip(*split))): - if any(node != nodes[0] for node in nodes): - suffix_nodes_in_common = i - break - if suffix_nodes_in_common: - split = [nodes[:-suffix_nodes_in_common] for nodes in split] - - return [".".join(nodes) for nodes in split] - - -class GraphiteStatusCheck(StatusCheck): - - class Meta(StatusCheck.Meta): - proxy = True - - @property - def check_category(self): - return "Metric check" - - def format_error_message(self, failures, actual_hosts, hosts_by_target): - if actual_hosts < self.expected_num_hosts: - return "Hosts missing | %d/%d hosts" % ( - actual_hosts, self.expected_num_hosts) - elif actual_hosts > 1: - threshold = float(self.value) - failures_by_host = ["%s: %s %s %0.1f" % ( - hosts_by_target[target], value, self.check_type, threshold) - for target, value in failures] - return ", ".join(failures_by_host) - else: - target, value = failures[0] - return "%s %s %0.1f" % (value, self.check_type, float(self.value)) - - def _run(self): - if not hasattr(self, 'utcnow'): - self.utcnow = None - result = StatusCheckResult(status_check=self) - - failures = [] - - last_result = self.last_result() - if last_result: - last_result_started = last_result.time - time_to_check = max(self.frequency, ((timezone.now() - last_result_started).total_seconds() / 60) + 1) - else: - time_to_check = self.frequency - - graphite_output = parse_metric(self.metric, mins_to_check=time_to_check, utcnow=self.utcnow) - - try: - result.raw_data = json.dumps(graphite_output['raw']) - except: - result.raw_data = graphite_output['raw'] - - if graphite_output["error"]: - result.succeeded = False - result.error = graphite_output["error"] - return result - - if graphite_output['num_series_with_data'] > 0: - result.average_value = graphite_output['average_value'] - for s in graphite_output['series']: - if not s["values"]: - continue - failure_value = None - if self.check_type == '<': - if float(s['min']) < float(self.value): - failure_value = s['min'] - elif self.check_type == '<=': - if float(s['min']) <= float(self.value): - failure_value = s['min'] - elif self.check_type == '>': - if float(s['max']) > float(self.value): - failure_value = s['max'] - elif self.check_type == '>=': - if float(s['max']) >= float(self.value): - failure_value = s['max'] - elif self.check_type == '==': - if float(self.value) in s['values']: - failure_value = float(self.value) - else: - raise Exception(u'Check type %s not supported' % - self.check_type) - - if not failure_value is None: - failures.append((s["target"], failure_value)) - - if len(failures) > self.allowed_num_failures: - result.succeeded = False - elif graphite_output['num_series_with_data'] < self.expected_num_hosts: - result.succeeded = False - else: - result.succeeded = True - - if not result.succeeded: - targets = [s["target"] for s in graphite_output["series"]] - hosts = minimize_targets(targets) - hosts_by_target = dict(zip(targets, hosts)) - - result.error = self.format_error_message( - failures, - graphite_output['num_series_with_data'], - hosts_by_target, - ) - - return result + def __str__(self): + return self.name -class HttpStatusCheck(StatusCheck): - class Meta(StatusCheck.Meta): - proxy = True - - @property - def check_category(self): - return "HTTP check" - - @classmethod - def _check_content_pattern(self, text_match, content): - content = content if isinstance(content, unicode) else unicode(content, "UTF-8") - return re.search(text_match, content) - - def _run(self): - result = StatusCheckResult(status_check=self) - - auth = None - if self.username or self.password: - auth = (self.username if self.username is not None else '', - self.password if self.password is not None else '') - - try: - resp = requests.get( - self.endpoint, - timeout=self.timeout, - verify=self.verify_ssl_certificate, - auth=auth, - headers={ - "User-Agent": settings.HTTP_USER_AGENT, - }, - ) - except requests.RequestException as e: - result.error = u'Request error occurred: %s' % (e.message,) - result.succeeded = False - else: - if self.status_code and resp.status_code != int(self.status_code): - result.error = u'Wrong code: got %s (expected %s)' % ( - resp.status_code, int(self.status_code)) - result.succeeded = False - result.raw_data = resp.text - elif self.text_match: - if not self._check_content_pattern(self.text_match, resp.text): - result.error = u'Failed to find match regex /%s/ in response body' % self.text_match - result.raw_data = resp.text - result.succeeded = False - else: - result.succeeded = True - else: - result.succeeded = True - return result class StatusCheckResult(models.Model): @@ -852,119 +819,8 @@ def short_error(self): return self.error def save(self, *args, **kwargs): - if isinstance(self.raw_data, basestring): + if isinstance(self.raw_data, str): self.raw_data = self.raw_data[:RAW_DATA_LIMIT] return super(StatusCheckResult, self).save(*args, **kwargs) + -class AlertAcknowledgement(models.Model): - time = models.DateTimeField() - user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) - service = models.ForeignKey(Service, on_delete=models.CASCADE) - cancelled_time = models.DateTimeField(null=True, blank=True) - cancelled_user = models.ForeignKey( - settings.AUTH_USER_MODEL, - null=True, - blank=True, - related_name='cancelleduser_set', - on_delete=models.CASCADE, - ) - - def unexpired(self): - return self.expires() > timezone.now() - - def expires(self): - return self.time + timedelta(minutes=settings.ACKNOWLEDGEMENT_EXPIRY) - - -class UserProfile(models.Model): - user = models.OneToOneField(settings.AUTH_USER_MODEL, related_name='profile', on_delete=models.CASCADE) - - def user_data(self): - for user_data_subclass in AlertPluginUserData.__subclasses__(): - user_data = user_data_subclass.objects.get_or_create(user=self, title=user_data_subclass.name) - return AlertPluginUserData.objects.filter(user=self) - - def __unicode__(self): - return 'User profile: %s' % self.user.username - - def save(self, *args, **kwargs): - # Enforce uniqueness - if self.fallback_alert_user: - profiles = UserProfile.objects.exclude(id=self.id) - profiles.update(fallback_alert_user=False) - return super(UserProfile, self).save(*args, **kwargs) - - @property - def prefixed_mobile_number(self): - return '+%s' % self.mobile_number - - mobile_number = models.CharField(max_length=20, blank=True, default='') - hipchat_alias = models.CharField(max_length=50, blank=True, default='') - fallback_alert_user = models.BooleanField(default=False) - -def create_user_profile(sender, instance, created, **kwargs): - if created: - UserProfile.objects.create(user=instance) - -post_save.connect(create_user_profile, sender=settings.AUTH_USER_MODEL) - - -class Shift(models.Model): - start = models.DateTimeField() - end = models.DateTimeField() - user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) - uid = models.TextField() - last_modified = models.DateTimeField() - deleted = models.BooleanField(default=False) - - def __unicode__(self): - deleted = '' - if self.deleted: - deleted = ' (deleted)' - return "%s: %s to %s%s" % (self.user.username, self.start, self.end, deleted) - - -def get_duty_officers(at_time=None): - """Returns a list of duty officers for a given time or now if none given""" - duty_officers = [] - if not at_time: - at_time = timezone.now() - current_shifts = Shift.objects.filter( - deleted=False, - start__lt=at_time, - end__gt=at_time, - ) - if current_shifts: - duty_officers = [shift.user for shift in current_shifts] - return duty_officers - else: - try: - u = UserProfile.objects.get(fallback_alert_user=True) - return [u.user] - except UserProfile.DoesNotExist: - return [] - - -def update_shifts(): - events = get_events() - users = User.objects.filter(is_active=True) - user_lookup = {} - for u in users: - user_lookup[u.username.lower()] = u - future_shifts = Shift.objects.filter(start__gt=timezone.now()) - future_shifts.update(deleted=True) - - for event in events: - e = event['summary'].lower().strip() - if e in user_lookup: - user = user_lookup[e] - # Delete any events that have been updated in ical - Shift.objects.filter(uid=event['uid'], - last_modified__lt=event['last_modified']).delete() - Shift.objects.get_or_create( - uid=event['uid'], - start=event['start'], - end=event['end'], - last_modified=event['last_modified'], - user=user, - deleted=False) diff --git a/cabot/cabotapp/plugins_a_borrar/__init__.py b/cabot/cabotapp/plugins_a_borrar/__init__.py new file mode 100644 index 000000000..ab4d88dc8 --- /dev/null +++ b/cabot/cabotapp/plugins_a_borrar/__init__.py @@ -0,0 +1,4 @@ +#from .jenkins_check_plugin import * +#from .graphite_status_check import * +#from .icmp_status_check import * +#from .http_status_check import * \ No newline at end of file diff --git a/cabot/cabotapp/plugins_a_borrar/graphite_status_check_delete.py b/cabot/cabotapp/plugins_a_borrar/graphite_status_check_delete.py new file mode 100644 index 000000000..89e934ec4 --- /dev/null +++ b/cabot/cabotapp/plugins_a_borrar/graphite_status_check_delete.py @@ -0,0 +1,146 @@ +from ..models import StatusCheck + +class GraphiteStatusCheck(StatusCheck): + + class Meta(StatusCheck.Meta): + proxy = True + + @property + def check_category(self): + return "Metric check" + + def format_error_message(self, failures, actual_hosts, hosts_by_target): + if actual_hosts < self.expected_num_hosts: + return "Hosts missing | %d/%d hosts" % ( + actual_hosts, self.expected_num_hosts) + elif actual_hosts > 1: + threshold = float(self.value) + failures_by_host = ["%s: %s %s %0.1f" % ( + hosts_by_target[target], value, self.check_type, threshold) + for target, value in failures] + return ", ".join(failures_by_host) + else: + target, value = failures[0] + return "%s %s %0.1f" % (value, self.check_type, float(self.value)) + + def _run(self): + if not hasattr(self, 'utcnow'): + self.utcnow = None + result = StatusCheckResult(status_check=self) + + failures = [] + + last_result = self.last_result() + if last_result: + last_result_started = last_result.time + time_to_check = max(self.frequency, ((timezone.now() - last_result_started).total_seconds() / 60) + 1) + else: + time_to_check = self.frequency + + graphite_output = parse_metric(self.metric, mins_to_check=time_to_check, utcnow=self.utcnow) + + try: + result.raw_data = json.dumps(graphite_output['raw']) + except: + result.raw_data = graphite_output['raw'] + + if graphite_output["error"]: + result.succeeded = False + result.error = graphite_output["error"] + return result + + if graphite_output['num_series_with_data'] > 0: + result.average_value = graphite_output['average_value'] + for s in graphite_output['series']: + if not s["values"]: + continue + failure_value = None + if self.check_type == '<': + if float(s['min']) < float(self.value): + failure_value = s['min'] + elif self.check_type == '<=': + if float(s['min']) <= float(self.value): + failure_value = s['min'] + elif self.check_type == '>': + if float(s['max']) > float(self.value): + failure_value = s['max'] + elif self.check_type == '>=': + if float(s['max']) >= float(self.value): + failure_value = s['max'] + elif self.check_type == '==': + if float(self.value) in s['values']: + failure_value = float(self.value) + else: + raise Exception(u'Check type %s not supported' % + self.check_type) + + if not failure_value is None: + failures.append((s["target"], failure_value)) + + if len(failures) > self.allowed_num_failures: + result.succeeded = False + elif graphite_output['num_series_with_data'] < self.expected_num_hosts: + result.succeeded = False + else: + result.succeeded = True + + if not result.succeeded: + targets = [s["target"] for s in graphite_output["series"]] + hosts = minimize_targets(targets) + hosts_by_target = dict(zip(targets, hosts)) + + result.error = self.format_error_message( + failures, + graphite_output['num_series_with_data'], + hosts_by_target, + ) + + return result + + def __str__(self): + return self.name + + +class GraphiteStatusCheckForm(StatusCheckForm): + class Meta: + model = GraphiteStatusCheck + fields = ( + 'name', + 'metric', + 'check_type', + 'value', + 'frequency', + 'active', + 'importance', + 'expected_num_hosts', + 'allowed_num_failures', + 'debounce', + ) + widgets = dict(**base_widgets) + widgets.update({ + 'value': forms.TextInput(attrs={ + 'style': 'width: 100px', + 'placeholder': 'threshold value', + }), + 'metric': forms.TextInput(attrs={ + 'style': 'width: 100%', + 'placeholder': 'graphite metric key' + }), + 'check_type': forms.Select(attrs={ + 'data-rel': 'chosen', + }) + }) + + + +#views + +class GraphiteCheckUpdateView(CheckUpdateView): + model = GraphiteStatusCheck + form_class = GraphiteStatusCheckForm + + +class GraphiteCheckCreateView(CheckCreateView): + model = GraphiteStatusCheck + form_class = GraphiteStatusCheckForm + diff --git a/cabot/cabotapp/plugins_a_borrar/icmp_status_check_delete.py b/cabot/cabotapp/plugins_a_borrar/icmp_status_check_delete.py new file mode 100644 index 000000000..00cdbe606 --- /dev/null +++ b/cabot/cabotapp/plugins_a_borrar/icmp_status_check_delete.py @@ -0,0 +1,54 @@ +from ..models import StatusCheck, StatusCheckResult + +import subprocess + +class ICMPStatusCheck(StatusCheck): + class Meta(StatusCheck.Meta): + proxy = True + + @property + def check_category(self): + return "ICMP/Ping Check" + + def _run(self): + result = StatusCheckResult(status_check=self) + instances = self.instance_set.all() + target = self.instance_set.get().address + + args = ['ping', '-c', '1', target] + try: + # We redirect stderr to STDOUT because ping can write to both, depending on the kind of error. + subprocess.check_output(args, stderr=subprocess.STDOUT, shell=False) + result.succeeded = True + except subprocess.CalledProcessError as e: + result.succeeded = False + result.error = e.output + + return result + + def __str__(self): + return self.name + + +class ICMPStatusCheckForm(StatusCheckForm): + class Meta: + model = ICMPStatusCheck + fields = ( + 'name', + 'frequency', + 'importance', + 'active', + 'debounce', + ) + widgets = dict(**base_widgets) + + +#views +class ICMPCheckCreateView(CheckCreateView): + model = ICMPStatusCheck + form_class = ICMPStatusCheckForm + + +class ICMPCheckUpdateView(CheckUpdateView): + model = ICMPStatusCheck + form_class = ICMPStatusCheckForm diff --git a/cabot/cabotapp/models/jenkins_check_plugin.py b/cabot/cabotapp/plugins_a_borrar/jenkins_check_plugin_delete.py similarity index 79% rename from cabot/cabotapp/models/jenkins_check_plugin.py rename to cabot/cabotapp/plugins_a_borrar/jenkins_check_plugin_delete.py index 23d722efb..d1c352a2c 100644 --- a/cabot/cabotapp/models/jenkins_check_plugin.py +++ b/cabot/cabotapp/plugins_a_borrar/jenkins_check_plugin_delete.py @@ -3,7 +3,7 @@ from django.db import models from ..jenkins import get_job_status -from .base import StatusCheck, StatusCheckResult +from ..models import StatusCheck, StatusCheckResult class JenkinsStatusCheck(StatusCheck): @@ -75,6 +75,9 @@ def calculate_debounced_passing(self, recent_results, debounce=0): False if failing """ last_result = recent_results[0] + if last_result.consecutive_failures == None: + return True + return last_result.consecutive_failures <= debounce @@ -97,3 +100,40 @@ def create_default_jenkins_config(): jenkins_user=os.environ.get("JENKINS_USER", ""), jenkins_pass=os.environ.get("JENKINS_PASS", ""), ) + + + + + +class JenkinsStatusCheckForm(StatusCheckForm): + class Meta: + model = JenkinsStatusCheck + fields = ( + 'name', + 'importance', + 'debounce', + 'max_queued_build_time', + 'jenkins_config', + ) + widgets = dict(**base_widgets) + + + +#views + +class JenkinsCheckCreateView(CheckCreateView): + model = JenkinsStatusCheck + form_class = JenkinsStatusCheckForm + + def form_valid(self, form): + form.instance.frequency = 1 + return super(JenkinsCheckCreateView, self).form_valid(form) + + +class JenkinsCheckUpdateView(CheckUpdateView): + model = JenkinsStatusCheck + form_class = JenkinsStatusCheckForm + + def form_valid(self, form): + form.instance.frequency = 1 + return super(JenkinsCheckUpdateView, self).form_valid(form) diff --git a/cabot/cabotapp/plugins_a_borrar/urls_general b/cabot/cabotapp/plugins_a_borrar/urls_general new file mode 100644 index 000000000..2e11585ae --- /dev/null +++ b/cabot/cabotapp/plugins_a_borrar/urls_general @@ -0,0 +1,21 @@ + ''' + url(r'^icmpcheck/create/', view=ICMPCheckCreateView.as_view(), + name='create-icmp-check'), + url(r'^icmpcheck/update/(?P\d+)/', + view=ICMPCheckUpdateView.as_view(), name='update-icmp-check'), + url(r'^icmpcheck/duplicate/(?P\d+)/', + view=duplicate_icmp_check, name='duplicate-icmp-check'), + url(r'^graphitecheck/create/', + view=GraphiteCheckCreateView.as_view(), name='create-graphite-check'), + url(r'^graphitecheck/update/(?P\d+)/', + view=GraphiteCheckUpdateView.as_view(), name='update-graphite-check'), + url(r'^graphitecheck/duplicate/(?P\d+)/', + view=duplicate_graphite_check, name='duplicate-graphite-check'), + url(r'^jenkins_check/create/', view=JenkinsCheckCreateView.as_view(), + name='create-jenkins-check'), + url(r'^jenkins_check/update/(?P\d+)/', + view=JenkinsCheckUpdateView.as_view(), name='update-jenkins-check'), + url(r'^jenkins_check/duplicate/(?P\d+)/', + view=duplicate_jenkins_check, + name='duplicate-jenkins-check'), + ''' \ No newline at end of file diff --git a/cabot/cabotapp/plugins_a_borrar/views_delete.py b/cabot/cabotapp/plugins_a_borrar/views_delete.py new file mode 100644 index 000000000..4b5242bfd --- /dev/null +++ b/cabot/cabotapp/plugins_a_borrar/views_delete.py @@ -0,0 +1,17 @@ +def duplicate_icmp_check(request, pk): + pc = StatusCheck.objects.get(pk=pk) + npk = pc.duplicate() + return HttpResponseRedirect(reverse('update-icmp-check', kwargs={'pk': npk})) + + + +def duplicate_graphite_check(request, pk): + pc = StatusCheck.objects.get(pk=pk) + npk = pc.duplicate() + return HttpResponseRedirect(reverse('update-graphite-check', kwargs={'pk': npk})) + + +def duplicate_jenkins_check(request, pk): + pc = StatusCheck.objects.get(pk=pk) + npk = pc.duplicate() + return HttpResponseRedirect(reverse('update-jenkins-check', kwargs={'pk': npk})) diff --git a/cabot/cabotapp/tasks.py b/cabot/cabotapp/tasks.py index f24bbd79b..468d43c6e 100644 --- a/cabot/cabotapp/tasks.py +++ b/cabot/cabotapp/tasks.py @@ -1,15 +1,16 @@ import logging import random -from celery.task import task + from django.conf import settings from django.utils import timezone from datetime import timedelta +from ..celery import app logger = logging.getLogger(__name__) -@task(ignore_result=True) +@app.task(ignote_result=True) def run_status_check(check_or_id): from .models import StatusCheck if not isinstance(check_or_id, StatusCheck): @@ -20,28 +21,30 @@ def run_status_check(check_or_id): check.run() -@task(ignore_result=True) +@app.task(ignote_result=True) def run_all_checks(): from .models import StatusCheck from datetime import timedelta checks = StatusCheck.objects.all() - seconds = range(60) - for check in checks: + for check in checks: if check.last_run: next_schedule = check.last_run + timedelta(minutes=check.frequency) + if (not check.last_run) or timezone.now() > next_schedule: - delay = random.choice(seconds) - logger.debug('Scheduling task for %s seconds from now' % delay) - run_status_check.apply_async((check.id,), countdown=delay) + #delay = random.choice(seconds) + #logger.debug('Scheduling task for %s seconds from now' % delay) + #run_status_check.apply_async((check.id,), countdown=delay) + run_status_check(check.id) + + -@task(ignore_result=True) +@app.task(ignote_result=True) def update_services(ignore_result=True): # Avoid importerrors and the like from legacy scheduling return -@task(ignore_result=True) def update_service(service_or_id): from .models import Service if not isinstance(service_or_id, Service): @@ -51,7 +54,8 @@ def update_service(service_or_id): service.update_status() -@task(ignore_result=True) + +@app.task(ignote_result=True) def update_instance(instance_or_id): from .models import Instance if not isinstance(instance_or_id, Instance): @@ -61,13 +65,13 @@ def update_instance(instance_or_id): instance.update_status() -@task(ignore_result=True) +@app.task(ignote_result=True) def update_shifts(): from .models import update_shifts as _update_shifts _update_shifts() -@task(ignore_result=True) +@app.task(ignote_result=True) def clean_db(days_to_retain=7, batch_size=10000): """ Clean up database otherwise it gets overwhelmed with StatusCheckResults. @@ -106,3 +110,5 @@ def clean_db(days_to_retain=7, batch_size=10000): 'days_to_retain': days_to_retain, 'batch_size': batch_size}, countdown=3) + + diff --git a/cabot/cabotapp/views.py b/cabot/cabotapp/views.py index 51635fd81..a6a1d1995 100644 --- a/cabot/cabotapp/views.py +++ b/cabot/cabotapp/views.py @@ -2,7 +2,7 @@ import re from datetime import date, datetime, timedelta from itertools import dropwhile, groupby, zip_longest - +import os import requests from .alert import AlertPlugin, AlertPluginUserData from cabot.cabotapp import alert @@ -28,15 +28,15 @@ from django.utils.timezone import utc from django.views.generic import (CreateView, DeleteView, DetailView, ListView, TemplateView, UpdateView, View) -from .models import (GraphiteStatusCheck, HttpStatusCheck, ICMPStatusCheck, - Instance, JenkinsStatusCheck, Service, Shift, StatusCheck, - StatusCheckResult, UserProfile, get_custom_check_plugins, +from .models import (Instance, Service, Shift, StatusCheck, StatusCheckResult, UserProfile, get_custom_check_plugins, get_duty_officers) + + +from django.apps import apps from rest_framework.views import APIView from rest_framework.response import Response from .tasks import run_status_check as _run_status_check -from .graphite import get_data, get_matching_metrics class LoginRequiredMixin(object): @@ -66,35 +66,12 @@ def run_status_check(request, pk): return HttpResponseRedirect(reverse('check', kwargs={'pk': pk})) -def duplicate_icmp_check(request, pk): - pc = StatusCheck.objects.get(pk=pk) - npk = pc.duplicate() - return HttpResponseRedirect(reverse('update-icmp-check', kwargs={'pk': npk})) - - def duplicate_instance(request, pk): instance = Instance.objects.get(pk=pk) new_instance = instance.duplicate() return HttpResponseRedirect(reverse('update-instance', kwargs={'pk': new_instance})) -def duplicate_http_check(request, pk): - pc = StatusCheck.objects.get(pk=pk) - npk = pc.duplicate() - return HttpResponseRedirect(reverse('update-http-check', kwargs={'pk': npk})) - - -def duplicate_graphite_check(request, pk): - pc = StatusCheck.objects.get(pk=pk) - npk = pc.duplicate() - return HttpResponseRedirect(reverse('update-graphite-check', kwargs={'pk': npk})) - - -def duplicate_jenkins_check(request, pk): - pc = StatusCheck.objects.get(pk=pk) - npk = pc.duplicate() - return HttpResponseRedirect(reverse('update-jenkins-check', kwargs={'pk': npk})) - class BaseCommonView(object): def render_to_response(self, context, *args, **kwargs): @@ -146,7 +123,17 @@ def save(self, commit=True): instance.save() if instance.pk: for field in self.symmetrical_fields: - setattr(instance, field, self.cleaned_data[field]) + try: + if field == "service_set": + n_field = Service.objects.get(name=self.cleaned_data[field].first().name) + instance.service_set.add(n_field) + if field == "instance_set": + n_field = Instance.objects.get(id=self.cleaned_data[field].first().id) + instance.instance_set.add(n_field) + except: + pass + #setattr(instance, (field+".add"), n_field) + #instance,field,add(n_field) self.save_m2m() return instance @@ -187,110 +174,6 @@ class StatusCheckForm(SymmetricalForm): ) -class GraphiteStatusCheckForm(StatusCheckForm): - class Meta: - model = GraphiteStatusCheck - fields = ( - 'name', - 'metric', - 'check_type', - 'value', - 'frequency', - 'active', - 'importance', - 'expected_num_hosts', - 'allowed_num_failures', - 'debounce', - ) - widgets = dict(**base_widgets) - widgets.update({ - 'value': forms.TextInput(attrs={ - 'style': 'width: 100px', - 'placeholder': 'threshold value', - }), - 'metric': forms.TextInput(attrs={ - 'style': 'width: 100%', - 'placeholder': 'graphite metric key' - }), - 'check_type': forms.Select(attrs={ - 'data-rel': 'chosen', - }) - }) - - -class ICMPStatusCheckForm(StatusCheckForm): - class Meta: - model = ICMPStatusCheck - fields = ( - 'name', - 'frequency', - 'importance', - 'active', - 'debounce', - ) - widgets = dict(**base_widgets) - - -class HttpStatusCheckForm(StatusCheckForm): - class Meta: - model = HttpStatusCheck - fields = ( - 'name', - 'endpoint', - 'username', - 'password', - 'text_match', - 'status_code', - 'timeout', - 'verify_ssl_certificate', - 'frequency', - 'importance', - 'active', - 'debounce', - ) - widgets = dict(**base_widgets) - widgets.update({ - 'endpoint': forms.TextInput(attrs={ - 'style': 'width: 100%', - 'placeholder': 'https://www.example.org/', - }), - 'username': forms.TextInput(attrs={ - 'style': 'width: 30%', - }), - 'password': forms.PasswordInput(attrs={ - 'style': 'width: 30%', - # Prevent auto-fill with saved Cabot log-in credentials: - 'autocomplete': 'new-password', - }), - 'text_match': forms.TextInput(attrs={ - 'style': 'width: 100%', - 'placeholder': '[Aa]rachnys\s+[Rr]ules', - }), - 'status_code': forms.TextInput(attrs={ - 'style': 'width: 20%', - 'placeholder': '200', - }), - }) - - def clean_password(self): - new_password_value = self.cleaned_data['password'] - if new_password_value == '': - new_password_value = self.initial.get('password') - return new_password_value - - -class JenkinsStatusCheckForm(StatusCheckForm): - class Meta: - model = JenkinsStatusCheck - fields = ( - 'name', - 'importance', - 'debounce', - 'max_queued_build_time', - 'jenkins_config', - ) - widgets = dict(**base_widgets) - class InstanceForm(SymmetricalForm): symmetrical_fields = ('service_set',) @@ -494,53 +377,9 @@ def get_success_url(self): return reverse('check', kwargs={'pk': self.object.id}) -class ICMPCheckCreateView(CheckCreateView): - model = ICMPStatusCheck - form_class = ICMPStatusCheckForm - - -class ICMPCheckUpdateView(CheckUpdateView): - model = ICMPStatusCheck - form_class = ICMPStatusCheckForm - - -class GraphiteCheckUpdateView(CheckUpdateView): - model = GraphiteStatusCheck - form_class = GraphiteStatusCheckForm - -class GraphiteCheckCreateView(CheckCreateView): - model = GraphiteStatusCheck - form_class = GraphiteStatusCheckForm -class HttpCheckCreateView(CheckCreateView): - model = HttpStatusCheck - form_class = HttpStatusCheckForm - - -class HttpCheckUpdateView(CheckUpdateView): - model = HttpStatusCheck - form_class = HttpStatusCheckForm - - -class JenkinsCheckCreateView(CheckCreateView): - model = JenkinsStatusCheck - form_class = JenkinsStatusCheckForm - - def form_valid(self, form): - form.instance.frequency = 1 - return super(JenkinsCheckCreateView, self).form_valid(form) - - -class JenkinsCheckUpdateView(CheckUpdateView): - model = JenkinsStatusCheck - form_class = JenkinsStatusCheckForm - - def form_valid(self, form): - form.instance.frequency = 1 - return super(JenkinsCheckUpdateView, self).form_valid(form) - class StatusCheckListView(LoginRequiredMixin, CommonListView): model = StatusCheck @@ -846,7 +685,7 @@ class InstanceListView(LoginRequiredMixin, CommonListView): def get_queryset(self): return Instance.objects.all().order_by('name').prefetch_related('status_checks') - + class ServiceListView(LoginRequiredMixin, CommonListView): model = Service @@ -909,11 +748,20 @@ class InstanceCreateView(LoginRequiredMixin, CommonCreateView): def form_valid(self, form): ret = super(InstanceCreateView, self).form_valid(form) - if self.object.status_checks.filter(polymorphic_ctype__model='icmpstatuscheck').count() == 0: - self.generate_default_ping_check(self.object) + + try: + icmp = apps.get_model('icmp','ICMPStatusCheck') + except: + icmp = None + + if icmp: + + if self.object.status_checks.filter(polymorphic_ctype__model='icmpstatuscheck').count() == 0: + self.generate_default_ping_check(self.object) return ret def generate_default_ping_check(self, obj): + pc = ICMPStatusCheck( name="Default Ping Check for %s" % obj.name, frequency=5, @@ -942,7 +790,7 @@ def get_initial(self): pass return initial - + @login_required def acknowledge_alert(request, pk): diff --git a/cabot/celery.py b/cabot/celery.py index 6e270ebff..26ead9856 100644 --- a/cabot/celery.py +++ b/cabot/celery.py @@ -6,10 +6,16 @@ from django.conf import settings from celery import Celery -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'cabot.settings') +from .config import config_charge + +config_charge() + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', + 'cabot.settings') app = Celery('cabot') -app.config_from_object('cabot.celeryconfig') + +app.config_from_object('django.conf:settings', namespace='CELERY') app.autodiscover_tasks() app.conf.beat_schedule = { @@ -23,6 +29,6 @@ }, 'clean-db': { 'task': 'cabot.cabotapp.tasks.clean_db', - 'schedule': timedelta(seconds=60 * 60 * 24), + 'schedule': timedelta(seconds=120), }, -} +} \ No newline at end of file diff --git a/cabot/celeryconfig.py b/cabot/celeryconfig.py deleted file mode 100644 index 593810dc2..000000000 --- a/cabot/celeryconfig.py +++ /dev/null @@ -1,11 +0,0 @@ -import os -from cabot.settings_utils import environ_get_list - -broker_url = environ_get_list(['CELERY_BROKER_URL', 'CACHE_URL']) -# Set environment variable if you want to run tests without a redis instance - -task_always_eager = environ_get_list(['CELERY_ALWAYS_EAGER', 'CELERY_TASK_ALWAYS_EAGER'], False) -backend = os.environ.get('CELERY_RESULT_BACKEND', None) -task_default_queue = os.environ.get('CELERY_DEFAULT_QUEUE', 'celery') - -timezone = 'UTC' diff --git a/cabot/config.py b/cabot/config.py new file mode 100644 index 000000000..18d1c2c85 --- /dev/null +++ b/cabot/config.py @@ -0,0 +1,31 @@ +import os + + +def config_charge(): + config = open("conf/development.env", "r") + lines = config.read().splitlines() + config.close() + + for line in lines: + + key = '' + value = '' + divider = 0 + + if line != "": + if line[0] != "#": + + divider = line.find('=') + + key = line[:divider] + value = line[divider+1:] + + os.environ[key]=value + else: + pass + + + + + + \ No newline at end of file diff --git a/cabot/rest_urls.py b/cabot/rest_urls.py index 35c0a9a68..58f53408b 100644 --- a/cabot/rest_urls.py +++ b/cabot/rest_urls.py @@ -78,14 +78,16 @@ class ViewSet(viewset_class): arg_fields=status_check_fields, readonly=True, )) +''' router.register(r'icmp_checks', create_viewset( - arg_model=models.ICMPStatusCheck, + arg_model=plugins.ICMPStatusCheck, arg_fields=status_check_fields, )) + router.register(r'graphite_checks', create_viewset( - arg_model=models.GraphiteStatusCheck, + arg_model=plugins.GraphiteStatusCheck, arg_fields=status_check_fields + ( 'metric', 'check_type', @@ -94,9 +96,8 @@ class ViewSet(viewset_class): 'allowed_num_failures', ), )) - router.register(r'http_checks', create_viewset( - arg_model=models.HttpStatusCheck, + arg_model=plugins.HttpStatusCheck, arg_fields=status_check_fields + ( 'endpoint', 'username', @@ -107,15 +108,15 @@ class ViewSet(viewset_class): 'verify_ssl_certificate', ), )) - router.register(r'jenkins_checks', create_viewset( - arg_model=models.JenkinsStatusCheck, + arg_model=plugins.JenkinsStatusCheck, arg_fields=status_check_fields + ( 'max_queued_build_time', 'jenkins_config', ), )) +''' # User API is off by default, could expose/allow modifying dangerous fields if settings.EXPOSE_USER_API: router.register(r'users', create_viewset( diff --git a/cabot/settings.py b/cabot/settings.py index d615d1e05..ac998ab5b 100644 --- a/cabot/settings.py +++ b/cabot/settings.py @@ -5,11 +5,12 @@ from django.urls import reverse_lazy from cabot.settings_utils import environ_get_list, force_bool from cabot.cabot_config import * - settings_dir = os.path.dirname(__file__) PROJECT_ROOT = os.path.abspath(settings_dir) -DEBUG = force_bool(os.environ.get('DEBUG', True)) +import redis + +DEBUG = os.environ.get('DEBUG') ADMINS = ( ('Admin', os.environ.get('ADMIN_EMAIL', 'name@example.com')), @@ -20,16 +21,14 @@ if os.environ.get('CABOT_FROM_EMAIL'): DEFAULT_FROM_EMAIL = os.environ['CABOT_FROM_EMAIL'] -#DATABASES = {'default': dj_database_url.config()} - DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': 'cabot', - 'USER': 'root', - 'PASSWORD': 'root', - 'HOST': 'localhost', - 'PORT': '5432', + 'NAME': os.environ.get('DATABASE_NAME'), + 'USER': os.environ.get('DATABASE_USER'), + 'PASSWORD': os.environ.get('DATABASE_PASSWORD'), + 'HOST': os.environ.get('DATABASE_HOST'), + 'PORT': os.environ.get('DATABASE_PORT'), } } @@ -51,8 +50,7 @@ # timezone as the operating system. # If running in a Windows environment this must be set to the same as your # system time zone. -TIME_ZONE = os.environ.get('TIME_ZONE', 'Etc/UTC') - +TIME_ZONE = os.environ.get('TIME_ZONE') # Language code for this installation. All choices can be found here: # http://www.i18nguy.com/unicode/language-identifiers.html LANGUAGE_CODE = 'en-us' @@ -161,25 +159,33 @@ 'dal_select2', 'django.contrib.admin', 'bootstrapform', + 'django_celery_beat', ) +CELERY_BROKER_URL = os.environ.get('CELERY_BROKER_URL') +CELERY_RESULT_BACKEND = os.environ.get('CELERY_RESULT_BACKEND') +CELERY_BEAT_SCHEDULER = os.environ.get('CELERY_BEAT_SCHEDULER') + +CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler' + +timezone = os.environ.get('TIME_ZONE') + +DEFAULT_AUTO_FIELD = 'django.db.models.AutoField' AUTH_USER_MODEL = 'auth.User' # Load additional apps from configuration file CABOT_PLUGINS_ENABLED_PARSED = [] +#CABOT_PLUGINS_ENABLED = os.environ.get('CABOT_PLUGINS_ENABLED') + for plugin in CABOT_PLUGINS_ENABLED.split(","): # Hack to clean up if versions of plugins specified exploded = re.split(r'[<>=]+', plugin) CABOT_PLUGINS_ENABLED_PARSED.append(exploded[0]) + + INSTALLED_APPS += tuple(CABOT_PLUGINS_ENABLED_PARSED) -COMPRESS_PRECOMPILERS = ( - ('text/coffeescript', 'coffeecompressorcompiler.filter.CoffeeScriptCompiler'), - ('text/eco', - 'eco -i TEMPLATES {infile} && cat "$(echo "{infile}" | sed -e "s/\.eco$/.js/g")"'), - ('text/less', '/usr/bin/less {infile} > {outfile}'), -) # For the email settings we both accept old and new names EMAIL_HOST = environ_get_list(['EMAIL_HOST', 'SES_HOST'], 'localhost') @@ -247,7 +253,7 @@ 'propagate': True, }, 'django.request': { - 'handlers': ['console', 'log_file', 'mail_admins'], + 'handlers': ['console', 'log_file'], 'level': 'ERROR', 'propagate': False, }, @@ -325,3 +331,5 @@ EXPOSE_USER_API = force_bool(os.environ.get('EXPOSE_USER_API', False)) ENABLE_SUBSCRIPTION = force_bool(os.environ.get('ENABLE_SUBSCRIPTION', True)) ENABLE_DUTY_ROTA = force_bool(os.environ.get('ENABLE_DUTY_ROTA', True)) + + diff --git a/cabot/settings_utils.py b/cabot/settings_utils.py index 6c6164c00..642cc853d 100644 --- a/cabot/settings_utils.py +++ b/cabot/settings_utils.py @@ -3,11 +3,16 @@ def force_bool(val): - return strtobool(str(val)) - + if val == True or val == False: + return strtobool(str(val)) + else: + return False def environ_get_list(names, default=None): + for name in names: + if name in os.environ: + return os.environ[name] return default diff --git a/cabot/static/arachnys/css/base.less b/cabot/static/arachnys/css/base.less deleted file mode 100644 index 5b5067066..000000000 --- a/cabot/static/arachnys/css/base.less +++ /dev/null @@ -1,55 +0,0 @@ -body{ - padding-top:50px; -} -.form-group { - ul { - list-style-type: none; - padding: 5px 0 0 0; - } - - input[type="radio"] { - margin-top: -3px; - } -} - -tr.warning a { - text-decoration: line-through; -} - -#graphite_data_container { - max-height: 200px; - overflow: scroll; -} - -.ui-autocomplete { - max-height: 400px; - overflow-y: scroll; - font-size: 10px; -} - -.jqstooltip { - display: none; -} - -div.dataTables_paginate { - float: right; -} - -div.dataTables_info { - float: left; - margin: 20px 0; -} - -div.dataTables_length { - float: right; -} - -.messages { - margin: auto; - width: 50%; - margin-top: 10px; -} - -.navbar-brand > img { - display: inline-block; -} \ No newline at end of file diff --git a/cabot/templates/base.html b/cabot/templates/base.html index 7d737510c..f2ba54e82 100644 --- a/cabot/templates/base.html +++ b/cabot/templates/base.html @@ -22,18 +22,7 @@ Instance
  • -
  • - Graphite check -
  • -
  • - HTTP check -
  • -
  • - Jenkins check -
  • -
  • - ICMP check -
  • + {% for checktype in custom_check_types %}
  • diff --git a/cabot/templates/base_public.html b/cabot/templates/base_public.html index c15d18c55..e259742f7 100644 --- a/cabot/templates/base_public.html +++ b/cabot/templates/base_public.html @@ -15,7 +15,7 @@ - + @@ -25,11 +25,15 @@ {% compress js %} - {% endcompress %} @@ -105,22 +109,23 @@

    Warning!

    - {% endcompress %} {% endblock js %} diff --git a/cabot/templates/cabotapp/_statuscheck_list.html b/cabot/templates/cabotapp/_statuscheck_list.html index 88d443e9f..113bc9cd2 100644 --- a/cabot/templates/cabotapp/_statuscheck_list.html +++ b/cabot/templates/cabotapp/_statuscheck_list.html @@ -6,18 +6,7 @@

    {{ checks_type|capfirst }} checks

    -  {% if checks_type == "All" or checks_type == "Graphite" %} - - {% endif %} - {% if checks_type == "All" or checks_type == "Http" %} -   - {% endif %} - {% if checks_type == "All" or checks_type == "Jenkins" %} -   - {% endif %} - {% if checks_type == "All" or checks_type == "ICMP" %} -   - {% endif %} + {% for checktype in custom_check_types %} {% if checks_type == "All" or checks_type == checktype.check_name %}   diff --git a/cabot/templates/cabotapp/alertpluginuserdata_form.html b/cabot/templates/cabotapp/alertpluginuserdata_form.html index c03952b2c..5db85f400 100644 --- a/cabot/templates/cabotapp/alertpluginuserdata_form.html +++ b/cabot/templates/cabotapp/alertpluginuserdata_form.html @@ -40,7 +40,7 @@

    User Profile

    {% block js %} {{ block.super }} {% compress js %} - diff --git a/cabot/templates/cabotapp/instance_confirm_delete.html b/cabot/templates/cabotapp/instance_confirm_delete.html index 99a459624..74e3cbad6 100644 --- a/cabot/templates/cabotapp/instance_confirm_delete.html +++ b/cabot/templates/cabotapp/instance_confirm_delete.html @@ -11,7 +11,7 @@

    Delete instance

    {% block js %} {{ block.super }} {% compress js %} - {% endcompress %} diff --git a/cabot/templates/cabotapp/instance_detail.html b/cabot/templates/cabotapp/instance_detail.html index fdce7947e..c2197ff12 100644 --- a/cabot/templates/cabotapp/instance_detail.html +++ b/cabot/templates/cabotapp/instance_detail.html @@ -65,23 +65,7 @@
  • -
    - -{% include 'cabotapp/_statuscheck_list.html' with checks=instance.graphite_status_checks.all instance=instance checks_type="Graphite" %} - -
    - -{% include 'cabotapp/_statuscheck_list.html' with checks=instance.http_status_checks.all instance=instance checks_type="Http" %} - -
    - -{% include 'cabotapp/_statuscheck_list.html' with checks=instance.jenkins_status_checks.all instance=instance checks_type="Jenkins" %} - -
    - -{% include 'cabotapp/_statuscheck_list.html' with checks=instance.icmp_status_checks.all instance=instance checks_type="ICMP" %} -
    @@ -137,62 +121,97 @@

    Status check report

    {% compress js %} - {% endcompress %} {% endblock %} diff --git a/cabot/templates/cabotapp/instance_list.html b/cabot/templates/cabotapp/instance_list.html index 7a850012f..a4d651200 100644 --- a/cabot/templates/cabotapp/instance_list.html +++ b/cabot/templates/cabotapp/instance_list.html @@ -19,7 +19,7 @@

    + {% endcompress %} diff --git a/cabot/templates/cabotapp/plugin_settings_form.html b/cabot/templates/cabotapp/plugin_settings_form.html index 126361b3d..2dd2d8685 100644 --- a/cabot/templates/cabotapp/plugin_settings_form.html +++ b/cabot/templates/cabotapp/plugin_settings_form.html @@ -61,22 +61,31 @@ {% block js %} {{ block.super }} {% compress js %} - {% endcompress %} diff --git a/cabot/templates/cabotapp/service_confirm_delete.html b/cabot/templates/cabotapp/service_confirm_delete.html index dd037ed4f..6afd218cc 100644 --- a/cabot/templates/cabotapp/service_confirm_delete.html +++ b/cabot/templates/cabotapp/service_confirm_delete.html @@ -11,7 +11,7 @@

    Delete service

    {% block js %} {{ block.super }} {% compress js %} - {% endcompress %} diff --git a/cabot/templates/cabotapp/service_detail.html b/cabot/templates/cabotapp/service_detail.html index ab2822e8c..faa381c1b 100644 --- a/cabot/templates/cabotapp/service_detail.html +++ b/cabot/templates/cabotapp/service_detail.html @@ -91,17 +91,8 @@

    {% include 'cabotapp/_instance_list.html' with instances=service.instances.all %}

    -
    - -{% include 'cabotapp/_statuscheck_list.html' with checks=service.graphite_status_checks.all service=service checks_type="Graphite" %} - -
    - -{% include 'cabotapp/_statuscheck_list.html' with checks=service.http_status_checks.all service=service checks_type="Http" %} -
    -{% include 'cabotapp/_statuscheck_list.html' with checks=service.jenkins_status_checks.all service=service checks_type="Jenkins" %} {% for custom_check in custom_check_types %}
    @@ -188,62 +179,96 @@

    Documentation

    {% compress js %} - {% endcompress %} {% endblock %} diff --git a/cabot/templates/cabotapp/service_list.html b/cabot/templates/cabotapp/service_list.html index b68d69354..adcfb750a 100644 --- a/cabot/templates/cabotapp/service_list.html +++ b/cabot/templates/cabotapp/service_list.html @@ -19,15 +19,23 @@

    - $('.datatable').dataTable - sDom: "<'row-fluid'<'span6'l><'span6'f>r>t<'row-fluid'<'span12'i><'span12 center'p>>" - sPaginationType: "bootstrap" - iDisplayLength: 100 - oLanguage: - sLengthMenu: "_MENU_ records per page" - fnDrawCallback: () -> - $('.sparktristate').sparkline('html', {type: 'tristate'}) + {% endcompress %} {% endblock js %} diff --git a/cabot/templates/cabotapp/shift_list.html b/cabot/templates/cabotapp/shift_list.html index ab5bd601a..91c239911 100644 --- a/cabot/templates/cabotapp/shift_list.html +++ b/cabot/templates/cabotapp/shift_list.html @@ -45,7 +45,7 @@ {% load compress %} {{ block.super }} {% compress js %} - {% endcompress %} diff --git a/cabot/templates/cabotapp/statuscheck_confirm_delete.html b/cabot/templates/cabotapp/statuscheck_confirm_delete.html index f93abc962..36dc9742c 100644 --- a/cabot/templates/cabotapp/statuscheck_confirm_delete.html +++ b/cabot/templates/cabotapp/statuscheck_confirm_delete.html @@ -11,7 +11,7 @@

    Delete check

    {% block js %} {{ block.super }} {% compress js %} - {% endcompress %} diff --git a/cabot/templates/cabotapp/statuscheck_detail.html b/cabot/templates/cabotapp/statuscheck_detail.html index 199067c18..7c2091180 100644 --- a/cabot/templates/cabotapp/statuscheck_detail.html +++ b/cabot/templates/cabotapp/statuscheck_detail.html @@ -114,7 +114,7 @@

    Check results

    {% load compress %} {{ block.super }} {% compress js %} - {% endcompress %} diff --git a/cabot/templates/cabotapp/statuscheck_form.html b/cabot/templates/cabotapp/statuscheck_form.html index 94262b045..1ad26afe7 100644 --- a/cabot/templates/cabotapp/statuscheck_form.html +++ b/cabot/templates/cabotapp/statuscheck_form.html @@ -32,88 +32,141 @@

    {% if form.instance.id %}Edit check{% else %}New check{% endif %}

    {% block js %} {{ block.super }} {% compress js %} - {% endcompress %} diff --git a/cabot/templates/cabotapp/statuscheck_list.html b/cabot/templates/cabotapp/statuscheck_list.html index 101821b0e..2dc3c7077 100644 --- a/cabot/templates/cabotapp/statuscheck_list.html +++ b/cabot/templates/cabotapp/statuscheck_list.html @@ -10,15 +10,23 @@ {% load compress %} {{ block.super }} {% compress js %} - {% endcompress %} {% endblock js %} diff --git a/cabot/templates/cabotapp/statuscheckresult_detail.html b/cabot/templates/cabotapp/statuscheckresult_detail.html index 22ac63a89..d1f520b12 100644 --- a/cabot/templates/cabotapp/statuscheckresult_detail.html +++ b/cabot/templates/cabotapp/statuscheckresult_detail.html @@ -45,25 +45,47 @@

    Check result: {{ result.s {% compress js %} - {% endcompress %} {% endblock js %} diff --git a/cabot/urls.py b/cabot/urls.py index 477405e1f..b7462895c 100644 --- a/cabot/urls.py +++ b/cabot/urls.py @@ -4,12 +4,7 @@ from requests.api import request from cabot.cabotapp.views import ( about, run_status_check, graphite_api_data, checks_run_recently, - duplicate_icmp_check, duplicate_graphite_check, duplicate_http_check, duplicate_jenkins_check, duplicate_instance, acknowledge_alert, remove_acknowledgement, - GraphiteCheckCreateView, GraphiteCheckUpdateView, - HttpCheckCreateView, HttpCheckUpdateView, - ICMPCheckCreateView, ICMPCheckUpdateView, - JenkinsCheckCreateView, JenkinsCheckUpdateView, StatusCheckDeleteView, StatusCheckListView, StatusCheckDetailView, StatusCheckResultDetailView, StatusCheckReportView, UserProfileUpdateAlert, PluginSettingsView, AlertTestView, AlertTestPluginView, SetupView, OnCallView) @@ -50,7 +45,7 @@ def wrapper(request, *args, **kwargs): def home_authentication_switcher(request, *args, **kwargs): if cabot_needs_setup(): return redirect('first_time_setup') - if not request.user.is_authenticated(): + if not request.user.is_authenticated: return ServicePublicListView.as_view()(request, *args, **kwargs) else: return ServiceListView.as_view()(request, *args, **kwargs) @@ -67,12 +62,12 @@ def home_authentication_switcher(request, *args, **kwargs): url(r'^subscriptions/', view=subscriptions, name='subscriptions'), url(r'^accounts/login/', view=LoginView.as_view(), name='login'), - url(r'^accounts/logout/', LogoutView.as_view(), name='logout'), + url(r'^accounts/logout/', view=LogoutView.as_view(), name='logout'), url(r'^setup/', view=SetupView.as_view(), name='first_time_setup'), url(r'^accounts/password-reset/', - view=PasswordResetView, name='password-reset'), + view=PasswordResetView.as_view(), name='password-reset'), url(r'^accounts/password-reset-done/', - view=PasswordResetDoneView, name='password-reset-done'), + view=PasswordResetDoneView.as_view(), name='password-reset-done'), url(r'^accounts/password-reset-confirm/', view=PasswordResetConfirmView, name='password-reset-confirm'), url(r'^status/', view=checks_run_recently, @@ -109,7 +104,6 @@ def home_authentication_switcher(request, *args, **kwargs): view=InstanceDeleteView.as_view(), name='delete-instance'), url(r'^instance/(?P\d+)/', view=InstanceDetailView.as_view(), name='instance'), - url(r'^checks/$', view=StatusCheckListView.as_view(), name='checks'), url(r'^check/run/(?P\d+)/', @@ -120,33 +114,6 @@ def home_authentication_switcher(request, *args, **kwargs): view=StatusCheckDetailView.as_view(), name='check'), url(r'^checks/report/$', view=StatusCheckReportView.as_view(), name='checks-report'), - - url(r'^icmpcheck/create/', view=ICMPCheckCreateView.as_view(), - name='create-icmp-check'), - url(r'^icmpcheck/update/(?P\d+)/', - view=ICMPCheckUpdateView.as_view(), name='update-icmp-check'), - url(r'^icmpcheck/duplicate/(?P\d+)/', - view=duplicate_icmp_check, name='duplicate-icmp-check'), - url(r'^graphitecheck/create/', - view=GraphiteCheckCreateView.as_view(), name='create-graphite-check'), - url(r'^graphitecheck/update/(?P\d+)/', - view=GraphiteCheckUpdateView.as_view(), name='update-graphite-check'), - url(r'^graphitecheck/duplicate/(?P\d+)/', - view=duplicate_graphite_check, name='duplicate-graphite-check'), - url(r'^httpcheck/create/', view=HttpCheckCreateView.as_view(), - name='create-http-check'), - url(r'^httpcheck/update/(?P\d+)/', - view=HttpCheckUpdateView.as_view(), name='update-http-check'), - url(r'^httpcheck/duplicate/(?P\d+)/', - view=duplicate_http_check, name='duplicate-http-check'), - url(r'^jenkins_check/create/', view=JenkinsCheckCreateView.as_view(), - name='create-jenkins-check'), - url(r'^jenkins_check/update/(?P\d+)/', - view=JenkinsCheckUpdateView.as_view(), name='update-jenkins-check'), - url(r'^jenkins_check/duplicate/(?P\d+)/', - view=duplicate_jenkins_check, - name='duplicate-jenkins-check'), - url(r'^result/(?P\d+)/', view=StatusCheckResultDetailView.as_view(), name='result'), url(r'^shifts/', view=ShiftListView.as_view(), @@ -186,10 +153,9 @@ def append_plugin_urls(): pass else: urlpatterns += [ - url(r'^plugins/%s/' % plugin, include('%s.urls' % plugin)) + url(r'^plugins/%s/' % plugin, include('%s.urls' % plugin)) ] - append_plugin_urls() if settings.AUTH_SOCIAL: @@ -201,3 +167,6 @@ def append_plugin_urls(): urlpatterns = [ url(r'^%s/' % settings.URL_PREFIX.strip('/'), include(urlpatterns)) ] + + + diff --git a/conf/default.env b/conf/default.env index 7bed20454..fd289b60d 100644 --- a/conf/default.env +++ b/conf/default.env @@ -1,5 +1,5 @@ # Plugins to be loaded at launch -#CABOT_PLUGINS_ENABLED=cabot_alert_hipchat,cabot_alert_twilio,cabot_alert_email,cabot_alert_slack +CABOT_PLUGINS_ENABLED=cabot_alert_hipchat,cabot_alert_twilio,cabot_alert_email,cabot_alert_slack DEBUG=t DATABASE_URL=postgres://postgres@db:5432/postgres diff --git a/deprecated!/.coveragerc b/deprecated!/.coveragerc new file mode 100644 index 000000000..0241cc7ad --- /dev/null +++ b/deprecated!/.coveragerc @@ -0,0 +1,6 @@ +[run] +branch = True +plugins = + django_coverage_plugin + +omit = *migrations* diff --git a/deprecated!/.foreman b/deprecated!/.foreman new file mode 100644 index 000000000..f8e5e002a --- /dev/null +++ b/deprecated!/.foreman @@ -0,0 +1,4 @@ +# vi: set ft=yaml : + +procfile: Procfile.dev +env: conf/production.env diff --git a/deprecated!/CHANGES b/deprecated!/CHANGES new file mode 100644 index 000000000..a80a04b5a --- /dev/null +++ b/deprecated!/CHANGES @@ -0,0 +1,272 @@ +Version 0.11.16 +--------------- + +* Upgrade celery and kombu + +Version 0.11.15 +--------------- + +* Fix dockerfile +* Add support for changing default celery queue name (using CELERY_DEFAULT_QUEUE env variable) + +Version 0.11.14 +--------------- + +* Add support for celery SQS backend + +Version 0.11.13 +--------------- + +* Fix bug where jenkins checks were always passing +* Reduce Arachnys branding a bit +* Fix 404 page for logged out users +* Style forms with django-bootstrap-form +* [[#605](https://github.com/arachnys/cabot/issues/605)] Fix http check forms auto-filling username/password +* [[#607](https://github.com/arachnys/cabot/issues/607)] Fix checks for websites service non utf-8 content + +Version 0.11.12 +--------------- + +* Upgrade django to 1.11.11 +* Debounce JenkinsCheck on the number of job failures + - Previously it would fail after cabot checked the jenkins api N times, even if the jenkins job had only failed once + +Version 0.11.11 +--------------- + +* Fix /api/oncall endpoint not working with basic auth + +Version 0.11.10 +--------------- + +* Add /api/oncall endpoint + +Version 0.11.9 +-------------- + +* Fix issue where Jenkins environment variables were required on first launch + +Version 0.11.8 +-------------- + +* Bump cabot-alert-slack to 0.8.2 +* Update LDAP dependencies +* Add ENABLE_SUBSCRIPTION and ENABLE_DUTY_ROTA options +* [[#556](https://github.com/arachnys/cabot/issues/556)] Fix issue with HttpStatusCheck with unicode content + +Version 0.11.7 +-------------- + +* Fix check plugins not displaying checks correctly on service details page + +Version 0.11.6 +-------------- + +* Add cloudwatch check plugin to dockerfile by default + - Can be enabled by adding "cabot_check_cloudwatch" to CABOT_PLUGINS_ENABLED + +Version 0.11.5 +-------------- + +* Fix multiple jenkins configs not working properly + - Due to caching on the client, the first config to be checked would always be used + +Version 0.11.4 +-------------- + +* Switch from jenkinsapi to python-jenkins + - Fixes performance regression introduced in 0.11 + +Version 0.11.3 +-------------- + +* [[#551](https://github.com/arachnys/cabot/issues/551)] Fix in-progress jenkins jobs being marked as failing + +Version 0.11.2 +-------------- + +* Fix pypi source distribution missing requirements for setup.py + +Version 0.11.1 +-------------- + +* Fix migration disassociating checks from services/instances +* Fix migration requiring jenkins environment variables are set +* Reduce time to store old check results to 7 days + - Currently stores for 2 months, but there's no actual way to view the old data. + +Version 0.11.0 +-------------- + +*** BROKEN RELEASE - MIGRATIONS DON'T WORK CORRECTLY *** + +* Jenkins support: + - Fail Jenkins checks when job is unknown + - Use [jenkinsapi](https://pypi.python.org/pypi/jenkinsapi) to talk to Jenkins + - Add option to specify multiple Jenkins backends + > NOTE: This update will delete any recent status check results for jenkins checks +* Add view for public services +* Add support for Google OAuth login +* Add ability to add custom check plugins + - See https://gitlab.com/as-public/cabot-check-skeleton for an example +* Remove deprecated Fabfile and Shell scripts + +Version 0.10.8 +-------------- + +* Update slack alert to 0.8.1 + - fixes names not linking + - only shows the acknowledge button if "SLACK_INTERACTIVE_MESSAGES" is set + - (The feature only works if set up correctly on the slack end) +* Update to django 1.11 (with working django-polymorphic this time) + +Version 0.10.7 +-------------- + +* Update slack alert plugin + - Now shows an "acknowledge" button within slack +* Fix alert tests not triggering if: + - A user had acknowledged working on the service + - A legitimate alert had been sent recently +* Add support for GitHub OAuth logins + - See http://cabotapp.com/use/users.html + +Version 0.10.6 +-------------- + +* Fix plugin urls being overridden by plugin settings urls + - This fixes e.g. the twilio callback url not working +* Fix profile settings sidebar links not working + +Version 0.10.5 +-------------- + +* Fix bug which caused status graphs to sometimes not render +* Fix issue with complex recurring calendar - `'vDDDLists' object is not iterable` +* Fix css regression in logo/title + +Version 0.10.4 +-------------- + +* Fix basic auth passwords getting reset when editing checks +* Fix plugin alert tests alerting the current duty officer + - They should now always alert only the user that runs the test + +Version 0.10.3 +-------------- + +* Add plugin settings views with the ability to test alerts. +* Allow user filter for LDAP to be configured + - Set the AUTH_LDAP_USER_FILTER setting to change it (defaults to "(uid=%(user)s)") +* Update cabot-alert-hipchat plugin to 2.0.2 + - Fixes bug when both HIPCHAT_URL and HIPCHAT_DOMAIN were set + +Version 0.10.2 +-------------- + +* Update cabot-alert-hipchat plugin to 2.0.1 + - Supports Hipchat API v2 + - If HIPCHAT_URL is set, it will use the old v1 api + - Use HIPCHAT_DOMAIN for custom hipchat v2 deployments +* Add interactive api docs (using djangorestframework 3.6) at /docs + +Version 0.10.1 +-------------- + +* [BUGFIX] Update cabot_alert_twilio to 1.3.1 + - 1.3.0 was still broken on django 1.10 + +Version 0.10.0 +-------------- + +* Add feedback notifications when updated profile +* Automatically reload plugins after migrating +* Add cabot_alert_slack as default plugin +* Upgrade to Django 1.10 +* Upgrade to Celery 4 + +Version 0.9.2 +------------- + +* Add /about endpoint +* Fix rota bug when ical had no timezone +* Add User Profile settings link to user dropdown + +Version 0.9.1 +------------- + +* Update cabot-alert-twilio to 1.3.0 to work on django 1.10 +* Fix Alert preferences form breaking on django 1.8 +* Add `cabot` executable instead of using python manage.py (for e.g. migrating) + +Version 0.9.0 +------------- + +* Upgrade to Django 1.9 + +Version 0.8.7 +------------- + +* Fix Alert preferences form breaking on django 1.8 + +Version 0.8.6 +------------- + +* Add first time setup page +* Remove create_cabot_superuser management command (redundant with first time setup) + +Version 0.8.5 +------------- + +* More severe alerts should trigger even if a less severe alert was recently sent +* Update production.env.example email settings +* Convert environment vars to boolean nicely + +> Note: You may have to update your settings if they contain invalid boolean values + +Version 0.8.4 +------------- + +* Fix setup.py packaging +* Use whitenoise to serve static files + +> Note: You may have to update your webserver settings for static files to work properly + +Version 0.8.3 +------------- + +* BUG: Add missing context processor + +Version 0.8.2 +------------- + +* Remove django-smtp-ssl dependency +* Build docker image from alpine +* Refactor docker-compose files +* Fix db_clean task failing on large results tables +* Wait for docker containers to start in docker-entrypoint.sh +* Update CABOT_PLUGINS_ENABLED to compatible plugin versions +* Automatically initialise database, assets and superuser on docker container start + +Version 0.8.1 +------------- + +* Fix all workers running celery beat +* Update django-compressor to run on django 1.8 +* Fix typo in url testcase +* Update wsgi.py to work with django 1.8 + +Version 0.8.0 +------------- + +* Upgraded to Django 1.8 + +Version 0.7.0 +------------- + +* Upgraded to Django 1.7 + +Version 0.6.0 +------------- + +* Versioning Introduced. diff --git "a/deprecated!/Documento sin t\303\255tulo" "b/deprecated!/Documento sin t\303\255tulo" new file mode 100644 index 000000000..84aad555e --- /dev/null +++ "b/deprecated!/Documento sin t\303\255tulo" @@ -0,0 +1,35 @@ + web: + build: . + extends: + file: docker-compose-base.yml + service: base + env_file: + - conf/development.env + command: python manage.py runserver 0.0.0.0:8000 + ports: + - "8000:8000" + links: + - redis + - db + + worker-beat: + extends: + file: docker-compose-base.yml + service: base + env_file: + - conf/development.env + command: celery -A cabot worker --beat --scheduler django --loglevel=info + environment: + - SKIP_INIT=1 + - WAIT_FOR_MIGRATIONS=1 + links: + - redis + - db + + + + + +ENTRYPOINT ["./docker-entrypoint.sh"] + + diff --git a/deprecated!/MANIFEST.in b/deprecated!/MANIFEST.in new file mode 100644 index 000000000..d46b60e18 --- /dev/null +++ b/deprecated!/MANIFEST.in @@ -0,0 +1,6 @@ +recursive-include cabot/.collectstatic * +recursive-include cabot/templates * +include requirements.txt +include requirements-plugins.txt +include requirements-dev.txt +include README.md diff --git a/deprecated!/Pipfile b/deprecated!/Pipfile new file mode 100644 index 000000000..ff32bedfa --- /dev/null +++ b/deprecated!/Pipfile @@ -0,0 +1,30 @@ +[[source]] +url = "https://pypi.python.org/simple" +verify_ssl = true + +[packages] +amqp = ">=2.1.4" +celery = ">=4,<5" +djangorestframework = "*" +django-jsonify = "*" +django-filter = "*" +django-auth-ldap = "*" +anyjson = "*" +dj-database-url = "*" +freezegun = "*" +gevent = "*" +gunicorn = "*" +icalendar = "*" +psycopg2 = "*" +python-dateutil = "*" +pytz = "*" +redis = "*" +requests = "*" +twilio = ">=5,<6" +whitenoise = "*" +coreapi = "*" +Django = ">=1.11,<2" +django_polymorphic = "*" +django_compressor = "*" +Markdown = "*" +Pygments = "*" diff --git a/deprecated!/Procfile b/deprecated!/Procfile new file mode 100644 index 000000000..dc603d723 --- /dev/null +++ b/deprecated!/Procfile @@ -0,0 +1,3 @@ +web: gunicorn cabot.wsgi:application --config gunicorn.conf +celery: celery worker -A cabot --loglevel=INFO --concurrency=16 -Ofair +beat: celery beat -A cabot --loglevel=INFO diff --git a/deprecated!/Procfile.dev b/deprecated!/Procfile.dev new file mode 100644 index 000000000..d3cecc003 --- /dev/null +++ b/deprecated!/Procfile.dev @@ -0,0 +1,3 @@ +web: python manage.py runserver 0.0.0.0:$PORT +celery: celery -A cabot worker --loglevel=DEBUG -c 8 -Ofair +beat: celery -A cabot beat --loglevel=DEBUG diff --git a/deprecated!/Vagrantfile b/deprecated!/Vagrantfile new file mode 100644 index 000000000..6c1fc0849 --- /dev/null +++ b/deprecated!/Vagrantfile @@ -0,0 +1,50 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : +require 'yaml' + +# Load local config overrides +local_config = File.file?("local_config.yml") ? YAML.load(File.read("local_config.yml")) : {} + +Vagrant::configure("2") do |config| + # All Vagrant configuration is done here. The most common configuration + # options are documented and commented below. For a complete reference, + # please see the online documentation at vagrantup.com. + + # Every Vagrant virtual environment requires a box to build off of. + config.vm.box = local_config["box"] || "hashicorp/precise64" + + # Virtualbox + config.vm.provider "virtualbox" do |vb| + vb.customize [ + "modifyvm", :id, + "--memory", local_config['ram'] || "1024", + "--cpus", local_config['cpu'] || 1, + "--ioapic", "on", + ] + end + + #vmware_fusion + config.vm.provider "vmware_fusion" do |v| + v.vmx["memsize"] = local_config['ram'] || "1024" + v.vmx["numvcpus"] = local_config['cpu'] || 1 + end + + # Boot with a GUI so you can see the screen. (Default is headless) + # config.vm.boot_mode = :gui + + # Assign this VM to a host-only network IP, allowing you to access it + # via the IP. Host-only networks can talk to the host machine as well as + # any other machines on the same network, but cannot be accessed (through this + # network interface) by any external networks. + config.vm.network "forwarded_port", guest: 5001, host: 5001 + + # Share an additional folder to the guest VM. The first argument is + # an identifier, the second is the path on the guest to mount the + # folder, and the third is the path on the host to the actual folder. + config.vm.synced_folder "./", "/vagrant", create: true + + # Provision the development environment + config.vm.provision :shell do |shell| + shell.inline = 'sudo /vagrant/bin/provision' + end +end diff --git a/deprecated!/celerybeat-schedule.bak b/deprecated!/celerybeat-schedule.bak new file mode 100644 index 000000000..1428527ab --- /dev/null +++ b/deprecated!/celerybeat-schedule.bak @@ -0,0 +1,4 @@ +'entries', (3072, 656) +'__version__', (512, 15) +'tz', (1024, 13) +'utc_enabled', (1536, 4) diff --git a/deprecated!/celerybeat-schedule.dat b/deprecated!/celerybeat-schedule.dat new file mode 100644 index 0000000000000000000000000000000000000000..ddfc9e86007b4497da74945d5abc65443f668417 GIT binary patch literal 3728 zcmeHI%Wl&^6m>|_B$Fn6h4L)WltXs*J~oo9i~j&OnFVpVaNlddY&t*Ua2 zOB|QqJUPY{j;pkV1s~T0u5;Ybl9EUsamlJ-QIaoe3x6UHfI0#5r)b||Nz&frxE0by zh?r<^bKH@%1&$)oF8f#!Smh|4CA2Cxq0;PUR$-Ct7q}}a);QMB)M}%z)xA)wa;R0s zp(${m{M& zUO5S*hk>Gl+Cx}l)9KaZyCUMhwucF74^(nVj?|!%>o*Dp_A{_-K9=1S1_OC-FPV@o lnB>Sv7i9mZ|AP!Z4c-3%?YH0juT&5Ing1ol`!B=x|97?(l`Q}O literal 0 HcmV?d00001 diff --git a/deprecated!/celerybeat-schedule.dir b/deprecated!/celerybeat-schedule.dir new file mode 100644 index 000000000..1428527ab --- /dev/null +++ b/deprecated!/celerybeat-schedule.dir @@ -0,0 +1,4 @@ +'entries', (3072, 656) +'__version__', (512, 15) +'tz', (1024, 13) +'utc_enabled', (1536, 4) diff --git a/deprecated!/docker-compose-base.yml b/deprecated!/docker-compose-base.yml new file mode 100644 index 000000000..1cc952e53 --- /dev/null +++ b/deprecated!/docker-compose-base.yml @@ -0,0 +1,10 @@ +version: '3' +services: + base: + build: . + image: t_dk + command: "false" + volumes: + - .:/code + env_file: + - conf/development.env diff --git a/deprecated!/docker-compose-test.yml b/deprecated!/docker-compose-test.yml new file mode 100644 index 000000000..d2c00a737 --- /dev/null +++ b/deprecated!/docker-compose-test.yml @@ -0,0 +1,13 @@ +version: '2' +services: + test: + extends: + file: docker-compose-base.yml + service: base + entrypoint: /usr/bin/python + command: manage.py test -v2 + env_file: + - conf/test.env + sut: + image: ubuntu + command: "true" diff --git a/deprecated!/docker-compose.yml b/deprecated!/docker-compose.yml new file mode 100644 index 000000000..4742c6724 --- /dev/null +++ b/deprecated!/docker-compose.yml @@ -0,0 +1,72 @@ +version: '3' +services: + db: + container_name: cabot_pg + image: postgres:alpine + restart: always + environment: + POSTGRES_USER: root + POSTGRES_PASSWORD: root + POSTGRES_DB: test_db + ports: + - "5432:5432" + volumes: + - datavolume:/var/lib/postgresql/data + + pgadmin: + container_name: cabot_pg_admin + image: dpage/pgadmin4 + restart: always + environment: + PGADMIN_DEFAULT_EMAIL: admin@admin.com + PGADMIN_DEFAULT_PASSWORD: root + ports: + - "5050:80" + + redis: + container_name: cabot_redis + image: redislabs/redismod + restart: always + ports: + - 6379:6379 + + redisinsight: + container_name: cabot_redis_admin + image: redislabs/redisinsight:latest + restart: always + ports: + - '8001:8001' + + web: + build: . + extends: + file: docker-compose-base.yml + service: base + env_file: + - conf/development.env + command: python manage.py migrate + command: python manage.py runserver 0.0.0.0:8000 + ports: + - "8000:8000" + links: + - redis + - db + + worker-beat: + extends: + file: docker-compose-base.yml + service: base + env_file: + - conf/development.env + command: celery -A cabot worker --beat --scheduler django --loglevel=info + environment: + - SKIP_INIT=1 + - WAIT_FOR_MIGRATIONS=1 + links: + - redis + - db + + +volumes: + datavolume: + diff --git a/deprecated!/example_local_config.yml b/deprecated!/example_local_config.yml new file mode 100644 index 000000000..b1081c5df --- /dev/null +++ b/deprecated!/example_local_config.yml @@ -0,0 +1,13 @@ +--- +# Example Local Vagrant config +# With this file, you can override the amount of RAM and CPUs allocated +# to the VM, as well as change the base box it uses. Just copy it to +# local_config.yml and edit with whatever values you want. +# +# Note that it doesn't take effect until you vagrant destroy && vagrant up + +# double your pleasure double your CPU and RAM +ram: 2048 +cpu: 2 +# hashicorp ubuntu doesn't support VMWare, so use box-cutter +box: box-cutter/ubuntu1404 diff --git a/deprecated!/get-docker.sh b/deprecated!/get-docker.sh new file mode 100644 index 000000000..3022001e4 --- /dev/null +++ b/deprecated!/get-docker.sh @@ -0,0 +1,525 @@ +#!/bin/sh +set -e +# Docker CE for Linux installation script +# +# See https://docs.docker.com/engine/install/ for the installation steps. +# +# This script is meant for quick & easy install via: +# $ curl -fsSL https://get.docker.com -o get-docker.sh +# $ sh get-docker.sh +# +# For test builds (ie. release candidates): +# $ curl -fsSL https://test.docker.com -o test-docker.sh +# $ sh test-docker.sh +# +# NOTE: Make sure to verify the contents of the script +# you downloaded matches the contents of install.sh +# located at https://github.com/docker/docker-install +# before executing. +# +# Git commit from https://github.com/docker/docker-install when +# the script was uploaded (Should only be modified by upload job): +SCRIPT_COMMIT_SHA="7cae5f8b0decc17d6571f9f52eb840fbc13b2737" + + +# The channel to install from: +# * nightly +# * test +# * stable +# * edge (deprecated) +DEFAULT_CHANNEL_VALUE="stable" +if [ -z "$CHANNEL" ]; then + CHANNEL=$DEFAULT_CHANNEL_VALUE +fi + +DEFAULT_DOWNLOAD_URL="https://download.docker.com" +if [ -z "$DOWNLOAD_URL" ]; then + DOWNLOAD_URL=$DEFAULT_DOWNLOAD_URL +fi + +DEFAULT_REPO_FILE="docker-ce.repo" +if [ -z "$REPO_FILE" ]; then + REPO_FILE="$DEFAULT_REPO_FILE" +fi + +mirror='' +DRY_RUN=${DRY_RUN:-} +while [ $# -gt 0 ]; do + case "$1" in + --mirror) + mirror="$2" + shift + ;; + --dry-run) + DRY_RUN=1 + ;; + --*) + echo "Illegal option $1" + ;; + esac + shift $(( $# > 0 ? 1 : 0 )) +done + +case "$mirror" in + Aliyun) + DOWNLOAD_URL="https://mirrors.aliyun.com/docker-ce" + ;; + AzureChinaCloud) + DOWNLOAD_URL="https://mirror.azure.cn/docker-ce" + ;; +esac + +# docker-ce-rootless-extras is packaged since Docker 20.10.0 +has_rootless_extras="1" +if echo "$VERSION" | grep -q '^1'; then + has_rootless_extras= +fi + +command_exists() { + command -v "$@" > /dev/null 2>&1 +} + +is_dry_run() { + if [ -z "$DRY_RUN" ]; then + return 1 + else + return 0 + fi +} + +is_wsl() { + case "$(uname -r)" in + *microsoft* ) true ;; # WSL 2 + *Microsoft* ) true ;; # WSL 1 + * ) false;; + esac +} + +is_darwin() { + case "$(uname -s)" in + *darwin* ) true ;; + *Darwin* ) true ;; + * ) false;; + esac +} + +deprecation_notice() { + distro=$1 + date=$2 + echo + echo "DEPRECATION WARNING:" + echo " The distribution, $distro, will no longer be supported in this script as of $date." + echo " If you feel this is a mistake please submit an issue at https://github.com/docker/docker-install/issues/new" + echo + sleep 10 +} + +get_distribution() { + lsb_dist="" + # Every system that we officially support has /etc/os-release + if [ -r /etc/os-release ]; then + lsb_dist="$(. /etc/os-release && echo "$ID")" + fi + # Returning an empty string here should be alright since the + # case statements don't act unless you provide an actual value + echo "$lsb_dist" +} + +add_debian_backport_repo() { + debian_version="$1" + backports="deb http://ftp.debian.org/debian $debian_version-backports main" + if ! grep -Fxq "$backports" /etc/apt/sources.list; then + (set -x; $sh_c "echo \"$backports\" >> /etc/apt/sources.list") + fi +} + +echo_docker_as_nonroot() { + if is_dry_run; then + return + fi + if command_exists docker && [ -e /var/run/docker.sock ]; then + ( + set -x + $sh_c 'docker version' + ) || true + fi + + # intentionally mixed spaces and tabs here -- tabs are stripped by "<<-EOF", spaces are kept in the output + echo + echo "================================================================================" + echo + if [ -n "$has_rootless_extras" ]; then + echo "To run Docker as a non-privileged user, consider setting up the" + echo "Docker daemon in rootless mode for your user:" + echo + echo " dockerd-rootless-setuptool.sh install" + echo + echo "Visit https://docs.docker.com/go/rootless/ to learn about rootless mode." + echo + fi + echo + echo "To run the Docker daemon as a fully privileged service, but granting non-root" + echo "users access, refer to https://docs.docker.com/go/daemon-access/" + echo + echo "WARNING: Access to the remote API on a privileged Docker daemon is equivalent" + echo " to root access on the host. Refer to the 'Docker daemon attack surface'" + echo " documentation for details: https://docs.docker.com/go/attack-surface/" + echo + echo "================================================================================" + echo +} + +# Check if this is a forked Linux distro +check_forked() { + + # Check for lsb_release command existence, it usually exists in forked distros + if command_exists lsb_release; then + # Check if the `-u` option is supported + set +e + lsb_release -a -u > /dev/null 2>&1 + lsb_release_exit_code=$? + set -e + + # Check if the command has exited successfully, it means we're in a forked distro + if [ "$lsb_release_exit_code" = "0" ]; then + # Print info about current distro + cat <<-EOF + You're using '$lsb_dist' version '$dist_version'. + EOF + + # Get the upstream release info + lsb_dist=$(lsb_release -a -u 2>&1 | tr '[:upper:]' '[:lower:]' | grep -E 'id' | cut -d ':' -f 2 | tr -d '[:space:]') + dist_version=$(lsb_release -a -u 2>&1 | tr '[:upper:]' '[:lower:]' | grep -E 'codename' | cut -d ':' -f 2 | tr -d '[:space:]') + + # Print info about upstream distro + cat <<-EOF + Upstream release is '$lsb_dist' version '$dist_version'. + EOF + else + if [ -r /etc/debian_version ] && [ "$lsb_dist" != "ubuntu" ] && [ "$lsb_dist" != "raspbian" ]; then + if [ "$lsb_dist" = "osmc" ]; then + # OSMC runs Raspbian + lsb_dist=raspbian + else + # We're Debian and don't even know it! + lsb_dist=debian + fi + dist_version="$(sed 's/\/.*//' /etc/debian_version | sed 's/\..*//')" + case "$dist_version" in + 10) + dist_version="buster" + ;; + 9) + dist_version="stretch" + ;; + 8|'Kali Linux 2') + dist_version="jessie" + ;; + esac + fi + fi + fi +} + +semverParse() { + major="${1%%.*}" + minor="${1#$major.}" + minor="${minor%%.*}" + patch="${1#$major.$minor.}" + patch="${patch%%[-.]*}" +} + +do_install() { + echo "# Executing docker install script, commit: $SCRIPT_COMMIT_SHA" + + if command_exists docker; then + docker_version="$(docker -v | cut -d ' ' -f3 | cut -d ',' -f1)" + MAJOR_W=1 + MINOR_W=10 + + semverParse "$docker_version" + + shouldWarn=0 + if [ "$major" -lt "$MAJOR_W" ]; then + shouldWarn=1 + fi + + if [ "$major" -le "$MAJOR_W" ] && [ "$minor" -lt "$MINOR_W" ]; then + shouldWarn=1 + fi + + cat >&2 <<-'EOF' + Warning: the "docker" command appears to already exist on this system. + + If you already have Docker installed, this script can cause trouble, which is + why we're displaying this warning and provide the opportunity to cancel the + installation. + + If you installed the current Docker package using this script and are using it + EOF + + if [ $shouldWarn -eq 1 ]; then + cat >&2 <<-'EOF' + again to update Docker, we urge you to migrate your image store before upgrading + to v1.10+. + + You can find instructions for this here: + https://github.com/docker/docker/wiki/Engine-v1.10.0-content-addressability-migration + EOF + else + cat >&2 <<-'EOF' + again to update Docker, you can safely ignore this message. + EOF + fi + + cat >&2 <<-'EOF' + + You may press Ctrl+C now to abort this script. + EOF + ( set -x; sleep 20 ) + fi + + user="$(id -un 2>/dev/null || true)" + + sh_c='sh -c' + if [ "$user" != 'root' ]; then + if command_exists sudo; then + sh_c='sudo -E sh -c' + elif command_exists su; then + sh_c='su -c' + else + cat >&2 <<-'EOF' + Error: this installer needs the ability to run commands as root. + We are unable to find either "sudo" or "su" available to make this happen. + EOF + exit 1 + fi + fi + + if is_dry_run; then + sh_c="echo" + fi + + # perform some very rudimentary platform detection + lsb_dist=$( get_distribution ) + lsb_dist="$(echo "$lsb_dist" | tr '[:upper:]' '[:lower:]')" + + if is_wsl; then + echo + echo "WSL DETECTED: We recommend using Docker Desktop for Windows." + echo "Please get Docker Desktop from https://www.docker.com/products/docker-desktop" + echo + cat >&2 <<-'EOF' + + You may press Ctrl+C now to abort this script. + EOF + ( set -x; sleep 20 ) + fi + + case "$lsb_dist" in + + ubuntu) + if command_exists lsb_release; then + dist_version="$(lsb_release --codename | cut -f2)" + fi + if [ -z "$dist_version" ] && [ -r /etc/lsb-release ]; then + dist_version="$(. /etc/lsb-release && echo "$DISTRIB_CODENAME")" + fi + ;; + + debian|raspbian) + dist_version="$(sed 's/\/.*//' /etc/debian_version | sed 's/\..*//')" + case "$dist_version" in + 10) + dist_version="buster" + ;; + 9) + dist_version="stretch" + ;; + 8) + dist_version="jessie" + ;; + esac + ;; + + centos|rhel) + if [ -z "$dist_version" ] && [ -r /etc/os-release ]; then + dist_version="$(. /etc/os-release && echo "$VERSION_ID")" + fi + ;; + + *) + if command_exists lsb_release; then + dist_version="$(lsb_release --release | cut -f2)" + fi + if [ -z "$dist_version" ] && [ -r /etc/os-release ]; then + dist_version="$(. /etc/os-release && echo "$VERSION_ID")" + fi + ;; + + esac + + # Check if this is a forked Linux distro + check_forked + + # Run setup for each distro accordingly + case "$lsb_dist" in + ubuntu|debian|raspbian) + pre_reqs="apt-transport-https ca-certificates curl" + if [ "$lsb_dist" = "debian" ]; then + # libseccomp2 does not exist for debian jessie main repos for aarch64 + if [ "$(uname -m)" = "aarch64" ] && [ "$dist_version" = "jessie" ]; then + add_debian_backport_repo "$dist_version" + fi + fi + + if ! command -v gpg > /dev/null; then + pre_reqs="$pre_reqs gnupg" + fi + apt_repo="deb [arch=$(dpkg --print-architecture)] $DOWNLOAD_URL/linux/$lsb_dist $dist_version $CHANNEL" + ( + if ! is_dry_run; then + set -x + fi + $sh_c 'apt-get update -qq >/dev/null' + $sh_c "DEBIAN_FRONTEND=noninteractive apt-get install -y -qq $pre_reqs >/dev/null" + $sh_c "curl -fsSL \"$DOWNLOAD_URL/linux/$lsb_dist/gpg\" | apt-key add -qq - >/dev/null" + $sh_c "echo \"$apt_repo\" > /etc/apt/sources.list.d/docker.list" + $sh_c 'apt-get update -qq >/dev/null' + ) + pkg_version="" + if [ -n "$VERSION" ]; then + if is_dry_run; then + echo "# WARNING: VERSION pinning is not supported in DRY_RUN" + else + # Will work for incomplete versions IE (17.12), but may not actually grab the "latest" if in the test channel + pkg_pattern="$(echo "$VERSION" | sed "s/-ce-/~ce~.*/g" | sed "s/-/.*/g").*-0~$lsb_dist" + search_command="apt-cache madison 'docker-ce' | grep '$pkg_pattern' | head -1 | awk '{\$1=\$1};1' | cut -d' ' -f 3" + pkg_version="$($sh_c "$search_command")" + echo "INFO: Searching repository for VERSION '$VERSION'" + echo "INFO: $search_command" + if [ -z "$pkg_version" ]; then + echo + echo "ERROR: '$VERSION' not found amongst apt-cache madison results" + echo + exit 1 + fi + search_command="apt-cache madison 'docker-ce-cli' | grep '$pkg_pattern' | head -1 | awk '{\$1=\$1};1' | cut -d' ' -f 3" + # Don't insert an = for cli_pkg_version, we'll just include it later + cli_pkg_version="$($sh_c "$search_command")" + pkg_version="=$pkg_version" + fi + fi + ( + if ! is_dry_run; then + set -x + fi + if [ -n "$cli_pkg_version" ]; then + $sh_c "apt-get install -y -qq --no-install-recommends docker-ce-cli=$cli_pkg_version >/dev/null" + fi + $sh_c "apt-get install -y -qq --no-install-recommends docker-ce$pkg_version >/dev/null" + # shellcheck disable=SC2030 + if [ -n "$has_rootless_extras" ]; then + # Install docker-ce-rootless-extras without "--no-install-recommends", so as to install slirp4netns when available + $sh_c "DEBIAN_FRONTEND=noninteractive apt-get install -y -qq docker-ce-rootless-extras$pkg_version >/dev/null" + fi + ) + echo_docker_as_nonroot + exit 0 + ;; + centos|fedora|rhel) + yum_repo="$DOWNLOAD_URL/linux/$lsb_dist/$REPO_FILE" + if ! curl -Ifs "$yum_repo" > /dev/null; then + echo "Error: Unable to curl repository file $yum_repo, is it valid?" + exit 1 + fi + if [ "$lsb_dist" = "fedora" ]; then + pkg_manager="dnf" + config_manager="dnf config-manager" + enable_channel_flag="--set-enabled" + disable_channel_flag="--set-disabled" + pre_reqs="dnf-plugins-core" + pkg_suffix="fc$dist_version" + else + pkg_manager="yum" + config_manager="yum-config-manager" + enable_channel_flag="--enable" + disable_channel_flag="--disable" + pre_reqs="yum-utils" + pkg_suffix="el" + fi + ( + if ! is_dry_run; then + set -x + fi + $sh_c "$pkg_manager install -y -q $pre_reqs" + $sh_c "$config_manager --add-repo $yum_repo" + + if [ "$CHANNEL" != "stable" ]; then + $sh_c "$config_manager $disable_channel_flag docker-ce-*" + $sh_c "$config_manager $enable_channel_flag docker-ce-$CHANNEL" + fi + $sh_c "$pkg_manager makecache" + ) + pkg_version="" + if [ -n "$VERSION" ]; then + if is_dry_run; then + echo "# WARNING: VERSION pinning is not supported in DRY_RUN" + else + pkg_pattern="$(echo "$VERSION" | sed "s/-ce-/\\\\.ce.*/g" | sed "s/-/.*/g").*$pkg_suffix" + search_command="$pkg_manager list --showduplicates 'docker-ce' | grep '$pkg_pattern' | tail -1 | awk '{print \$2}'" + pkg_version="$($sh_c "$search_command")" + echo "INFO: Searching repository for VERSION '$VERSION'" + echo "INFO: $search_command" + if [ -z "$pkg_version" ]; then + echo + echo "ERROR: '$VERSION' not found amongst $pkg_manager list results" + echo + exit 1 + fi + search_command="$pkg_manager list --showduplicates 'docker-ce-cli' | grep '$pkg_pattern' | tail -1 | awk '{print \$2}'" + # It's okay for cli_pkg_version to be blank, since older versions don't support a cli package + cli_pkg_version="$($sh_c "$search_command" | cut -d':' -f 2)" + # Cut out the epoch and prefix with a '-' + pkg_version="-$(echo "$pkg_version" | cut -d':' -f 2)" + fi + fi + ( + if ! is_dry_run; then + set -x + fi + # install the correct cli version first + if [ -n "$cli_pkg_version" ]; then + $sh_c "$pkg_manager install -y -q docker-ce-cli-$cli_pkg_version" + fi + $sh_c "$pkg_manager install -y -q docker-ce$pkg_version" + # shellcheck disable=SC2031 + if [ -n "$has_rootless_extras" ]; then + $sh_c "$pkg_manager install -y -q docker-ce-rootless-extras$pkg_version" + fi + ) + echo_docker_as_nonroot + exit 0 + ;; + *) + if [ -z "$lsb_dist" ]; then + if is_darwin; then + echo + echo "ERROR: Unsupported operating system 'macOS'" + echo "Please get Docker Desktop from https://www.docker.com/products/docker-desktop" + echo + exit 1 + fi + fi + echo + echo "ERROR: Unsupported distribution '$lsb_dist'" + echo + exit 1 + ;; + esac + exit 1 +} + +# wrapped up in a function so that we have some protection against only getting +# half the file during "curl | sh" +do_install diff --git a/deprecated!/gunicorn.conf b/deprecated!/gunicorn.conf new file mode 100644 index 000000000..0b989a5fb --- /dev/null +++ b/deprecated!/gunicorn.conf @@ -0,0 +1,7 @@ +# -*- mode: python -*- +# vi: set ft=python : + +import os + +bind = '127.0.0.1:%s' % os.environ['PORT'] +workers = 3 diff --git a/deprecated!/makemigrations b/deprecated!/makemigrations new file mode 100755 index 000000000..10176141d --- /dev/null +++ b/deprecated!/makemigrations @@ -0,0 +1,4 @@ +#!/bin/bash +rm dev.db +foreman run python manage.py syncdb +foreman run python manage.py migrate diff --git a/deprecated!/setup.cfg b/deprecated!/setup.cfg new file mode 100644 index 000000000..2eeeef9e1 --- /dev/null +++ b/deprecated!/setup.cfg @@ -0,0 +1,7 @@ +[isort] +known_first_party = cabot +multi_line_output = 0 +known_django = django,polymorphic,rest_framework +sections = FUTURE,STDLIB,THIRDPARTY,DJANGO,FIRSTPARTY,LOCALFOLDER +default_section = THIRDPARTY +skip_glob = **/migrations/* diff --git a/deprecated!/setup_dev.sh b/deprecated!/setup_dev.sh new file mode 100755 index 000000000..edd90ef78 --- /dev/null +++ b/deprecated!/setup_dev.sh @@ -0,0 +1,3 @@ +#!/bin/bash +foreman run python manage.py syncdb +foreman run python manage.py migrate diff --git a/deprecated!/upstart/process.conf.erb b/deprecated!/upstart/process.conf.erb new file mode 100644 index 000000000..c3df16525 --- /dev/null +++ b/deprecated!/upstart/process.conf.erb @@ -0,0 +1,6 @@ +start on starting <%= app %>-<%= name %> +stop on stopping <%= app %>-<%= name %> +respawn +respawn limit 50 5 + +exec su - <%= user %> -c 'cd <%= engine.root %>; export PORT=<%= port %>;<% engine.env.each_pair do |var,env| %> export <%= var.upcase %>='\''<%= env %>'\''; <% end %> export TMPDIR=$TMPDIR/<%= app %>/<%= name %>/<%= num %>; rm -rf $TMPDIR; mkdir -p $TMPDIR; source $VENV/bin/activate; <%= process.command %> >> <%= log %>/<%=name%>-<%=num%>.log 2>&1' diff --git a/manage.py b/manage.py index 83d770478..92e6d37e1 100755 --- a/manage.py +++ b/manage.py @@ -1,10 +1,18 @@ #!/usr/bin/env python import os import sys +from cabot.config import config_charge + + if __name__ == "__main__": + + #carga de enviroment + config_charge() + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cabot.settings") + from django.core.management import execute_from_command_line diff --git a/requirements-dev.txt b/requirements-dev.txt index 519a1a811..9b1bae445 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,6 +1,6 @@ -coverage==4.3.4 -django_coverage_plugin==1.5.0 -freezegun==0.3.9 -mock==2.0.0 -ipdb -isort==4.2.15 +coverage==5.5 +django-coverage-plugin==2.0.0 +freezegun==1.1.0 +mock==4.0.3 +ipdb==0.13.9 +isort==5.9.1 \ No newline at end of file diff --git a/requirements-plugins.txt b/requirements-plugins.txt index c3e50990c..e8765ad1e 100644 --- a/requirements-plugins.txt +++ b/requirements-plugins.txt @@ -1,5 +1,4 @@ -cabot_alert_email==1.4.3 -cabot_alert_hipchat==2.0.3 -cabot_alert_twilio==1.3.3 -cabot_alert_slack==0.8.3 -cabot_check_cloudwatch==0.1.2 +git+https://github.com/senzil/cabot-alert-email.git +git+https://github.com/senzil/cabot-check-http.git +git+https://github.com/senzil/cabot-alert-slack.git +git+https://github.com/senzil/cabot-check-network.git \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index dca9d9905..a52497dc0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,65 +1,128 @@ -amqp==2.1.4 +amqp==5.0.6 anyjson==0.3.3 -appdirs==1.4.3 -billiard==3.5.0.2 +appdirs==1.4.4 +argh==0.26.2 +asgiref==3.4.1 +astroid==2.6.2 +Babel==2.9.1 +backcall==0.2.0 +bashate==2.0.0 +billiard==3.6.4.0 boto==2.49.0 -boto3==1.9.86 -botocore==1.12.86 -celery==4.2.1 -coreapi==2.3.0 +boto3==1.17.106 +botocore==1.20.106 +cached-property==1.5.2 +cairocffi==1.0.0 +celery==5.1.2 +certifi==2021.5.30 +cffi==1.14.5 +chardet==4.0.0 +click==7.1.2 +click-didyoumean==0.0.3 +click-plugins==1.1.1 +click-repl==0.2.0 +coffee-compressor-compiler==0.2.0 +coreapi==2.3.3 coreschema==0.0.4 -dj-database-url==0.4.2 -Django==1.11.29 -django-appconf==1.0.2 -django-auth-ldap==1.2.16 -django-autocomplete-light==3.2.10 +cryptography==3.4.7 +decorator==5.0.9 +defusedxml==0.7.1 +dj-database-url==0.5.0 +Django==3.2.5 +django-appconf==1.0.4 +django-auth-ldap==2.4.0 +django-autocomplete-light==3.8.2 django-bootstrap-form==3.4 -django-compressor==2.2 -django-filter==1.0.4 +django-celery-beat==2.2.1 +django-common-helpers==0.9.2 +django-compressor==2.4.1 +django-crontab==0.7.1 +django-filter==2.4.0 django-jsonify==0.3.0 -django-polymorphic==1.3 -djangorestframework==3.6.2 -docutils==0.14 -futures==3.2.0 -gevent==1.2.1 -greenlet==0.4.12 -gunicorn==19.7.1 -httplib2==0.10.3 -icalendar==3.11.3 -itypes==1.1.0 -Jinja2==2.9.6 -jmespath==0.9.3 -kombu==4.2.2.post1 -Markdown==2.6.8 -MarkupSafe==1.0 +django-polymorphic==3.0.0 +django-tagging==0.4.3 +django-task==2.0.1 +django-timezone-field==4.2.1 +djangorestframework==3.12.4 +docutils==0.17.1 +dramatiq==1.11.0 +flake8==3.9.2 +gevent==21.1.2 +greenlet==1.1.0 +httplib2==0.19.1 +huey==2.3.2 +icalendar==4.0.7 +idna==2.10 +importlib-metadata==4.6.1 +ipython==7.16.1 +ipython-genutils==0.2.0 +itypes==1.2.0 +jedi==0.18.0 +Jinja2==3.0.1 +jmespath==0.10.0 +kombu==5.1.0 +lazy-object-proxy==1.6.0 +Markdown==3.3.4 +MarkupSafe==2.0.1 +mccabe==0.6.1 multi-key-dict==2.0.3 -oauthlib==3.0.0 -packaging==16.8 -pbr==5.1.1 -psycopg2==2.7.1 -pyasn1==0.4.5 -pyasn1-modules==0.2.3 -pycurl==7.43.0.1 -Pygments==2.2.0 -PyJWT==1.7.1 -pyparsing==2.2.0 -PySocks==1.6.7 -python-dateutil==2.6.0 -python-jenkins==0.4.15 -python-ldap==3.1.0 +oauthlib==3.1.1 +packaging==21.0 +parso==0.8.2 +pathtools==0.1.2 +pbr==5.6.0 +pexpect==4.8.0 +pickleshare==0.7.5 +pika==1.2.0 +prometheus-client==0.11.0 +prompt-toolkit==3.0.19 +psycopg2==2.7.7 +mysqlclient +psycopg2-binary==2.9.1 +ptyprocess==0.7.0 +pyasn1==0.4.8 +pyasn1-modules==0.2.8 +pycodestyle==2.7.0 +pycparser==2.20 +PyExecJS==1.5.1 +pyflakes==2.3.1 +Pygments==2.9.0 +PyJWT==2.1.0 +pylint==2.9.3 +pyparsing==2.4.7 +PySocks==1.7.1 +python-crontab==2.5.1 +python-dateutil==2.8.1 +python-jenkins==1.7.0 +python-ldap==3.3.1 python-openid==2.2.5 -pytz==2017.2 +python3-openid==3.2.0 +pytz==2021.1 +PyYAML==5.4.1 rcssmin==1.0.6 -redis==2.10.5 -requests==2.13.0 -requests-oauthlib==1.2.0 -rjsmin==1.0.12 -s3transfer==0.1.13 -six==1.10.0 -social-auth-app-django==1.1.0 -social-auth-core==3.0.0 -twilio==5.7.0 -uritemplate==3.0.0 -urllib3==1.24.1 -vine==1.1.3 -whitenoise==3.3.0 +redis==3.5.3 +requests==2.25.1 +requests-oauthlib==1.3.0 +rjsmin==1.1.0 +s3transfer==0.4.2 +scandir==1.10.0 +six==1.16.0 +social-auth-app-django==4.0.0 +social-auth-core==4.1.0 +sqlparse==0.4.1 +toml==0.10.2 +traitlets==4.3.3 +twilio==6.50.1 +typed-ast==1.4.3 +typing-extensions==3.10.0.0 +uritemplate==3.0.1 +urllib3==1.26.6 +vine==5.0.0 +watchdog==0.8.3 +watchdog-gevent==0.1.0 +wcwidth==0.2.5 +whitenoise==5.2.0 +wrapt==1.12.1 +zipp==3.5.0 +zope.event==4.5.0 +zope.interface==5.4.0 diff --git a/tox.ini b/tox.ini index d65853c37..3d6f8f2b9 100644 --- a/tox.ini +++ b/tox.ini @@ -12,7 +12,7 @@ commands = /bin/bash -c 'set -euo pipefail && . ./conf/development.env.example' [testenv:bashate] -deps = bashate==0.5.1 +deps = bashate==2.0.0 commands = # Run bashate check for all bash scripts # Ignores the following rules: From 10e922c0f0f81f4ffa2523efbe5886b2aaa71baf Mon Sep 17 00:00:00 2001 From: Ladrusca Date: Tue, 20 Jul 2021 15:18:26 -0300 Subject: [PATCH 04/24] completamente modularizada --- cabot/cabotapp/plugins_a_borrar/__init__.py | 4 - .../graphite_status_check_delete.py | 146 ------------------ .../icmp_status_check_delete.py | 54 ------- .../jenkins_check_plugin_delete.py | 139 ----------------- cabot/cabotapp/plugins_a_borrar/urls_general | 21 --- .../cabotapp/plugins_a_borrar/views_delete.py | 17 -- docker-compose-base.yml | 6 +- docker-compose.yml | 74 +++++---- 8 files changed, 49 insertions(+), 412 deletions(-) delete mode 100644 cabot/cabotapp/plugins_a_borrar/__init__.py delete mode 100644 cabot/cabotapp/plugins_a_borrar/graphite_status_check_delete.py delete mode 100644 cabot/cabotapp/plugins_a_borrar/icmp_status_check_delete.py delete mode 100644 cabot/cabotapp/plugins_a_borrar/jenkins_check_plugin_delete.py delete mode 100644 cabot/cabotapp/plugins_a_borrar/urls_general delete mode 100644 cabot/cabotapp/plugins_a_borrar/views_delete.py diff --git a/cabot/cabotapp/plugins_a_borrar/__init__.py b/cabot/cabotapp/plugins_a_borrar/__init__.py deleted file mode 100644 index ab4d88dc8..000000000 --- a/cabot/cabotapp/plugins_a_borrar/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -#from .jenkins_check_plugin import * -#from .graphite_status_check import * -#from .icmp_status_check import * -#from .http_status_check import * \ No newline at end of file diff --git a/cabot/cabotapp/plugins_a_borrar/graphite_status_check_delete.py b/cabot/cabotapp/plugins_a_borrar/graphite_status_check_delete.py deleted file mode 100644 index 89e934ec4..000000000 --- a/cabot/cabotapp/plugins_a_borrar/graphite_status_check_delete.py +++ /dev/null @@ -1,146 +0,0 @@ -from ..models import StatusCheck - -class GraphiteStatusCheck(StatusCheck): - - class Meta(StatusCheck.Meta): - proxy = True - - @property - def check_category(self): - return "Metric check" - - def format_error_message(self, failures, actual_hosts, hosts_by_target): - if actual_hosts < self.expected_num_hosts: - return "Hosts missing | %d/%d hosts" % ( - actual_hosts, self.expected_num_hosts) - elif actual_hosts > 1: - threshold = float(self.value) - failures_by_host = ["%s: %s %s %0.1f" % ( - hosts_by_target[target], value, self.check_type, threshold) - for target, value in failures] - return ", ".join(failures_by_host) - else: - target, value = failures[0] - return "%s %s %0.1f" % (value, self.check_type, float(self.value)) - - def _run(self): - if not hasattr(self, 'utcnow'): - self.utcnow = None - result = StatusCheckResult(status_check=self) - - failures = [] - - last_result = self.last_result() - if last_result: - last_result_started = last_result.time - time_to_check = max(self.frequency, ((timezone.now() - last_result_started).total_seconds() / 60) + 1) - else: - time_to_check = self.frequency - - graphite_output = parse_metric(self.metric, mins_to_check=time_to_check, utcnow=self.utcnow) - - try: - result.raw_data = json.dumps(graphite_output['raw']) - except: - result.raw_data = graphite_output['raw'] - - if graphite_output["error"]: - result.succeeded = False - result.error = graphite_output["error"] - return result - - if graphite_output['num_series_with_data'] > 0: - result.average_value = graphite_output['average_value'] - for s in graphite_output['series']: - if not s["values"]: - continue - failure_value = None - if self.check_type == '<': - if float(s['min']) < float(self.value): - failure_value = s['min'] - elif self.check_type == '<=': - if float(s['min']) <= float(self.value): - failure_value = s['min'] - elif self.check_type == '>': - if float(s['max']) > float(self.value): - failure_value = s['max'] - elif self.check_type == '>=': - if float(s['max']) >= float(self.value): - failure_value = s['max'] - elif self.check_type == '==': - if float(self.value) in s['values']: - failure_value = float(self.value) - else: - raise Exception(u'Check type %s not supported' % - self.check_type) - - if not failure_value is None: - failures.append((s["target"], failure_value)) - - if len(failures) > self.allowed_num_failures: - result.succeeded = False - elif graphite_output['num_series_with_data'] < self.expected_num_hosts: - result.succeeded = False - else: - result.succeeded = True - - if not result.succeeded: - targets = [s["target"] for s in graphite_output["series"]] - hosts = minimize_targets(targets) - hosts_by_target = dict(zip(targets, hosts)) - - result.error = self.format_error_message( - failures, - graphite_output['num_series_with_data'], - hosts_by_target, - ) - - return result - - def __str__(self): - return self.name - - -class GraphiteStatusCheckForm(StatusCheckForm): - class Meta: - model = GraphiteStatusCheck - fields = ( - 'name', - 'metric', - 'check_type', - 'value', - 'frequency', - 'active', - 'importance', - 'expected_num_hosts', - 'allowed_num_failures', - 'debounce', - ) - widgets = dict(**base_widgets) - widgets.update({ - 'value': forms.TextInput(attrs={ - 'style': 'width: 100px', - 'placeholder': 'threshold value', - }), - 'metric': forms.TextInput(attrs={ - 'style': 'width: 100%', - 'placeholder': 'graphite metric key' - }), - 'check_type': forms.Select(attrs={ - 'data-rel': 'chosen', - }) - }) - - - -#views - -class GraphiteCheckUpdateView(CheckUpdateView): - model = GraphiteStatusCheck - form_class = GraphiteStatusCheckForm - - -class GraphiteCheckCreateView(CheckCreateView): - model = GraphiteStatusCheck - form_class = GraphiteStatusCheckForm - diff --git a/cabot/cabotapp/plugins_a_borrar/icmp_status_check_delete.py b/cabot/cabotapp/plugins_a_borrar/icmp_status_check_delete.py deleted file mode 100644 index 00cdbe606..000000000 --- a/cabot/cabotapp/plugins_a_borrar/icmp_status_check_delete.py +++ /dev/null @@ -1,54 +0,0 @@ -from ..models import StatusCheck, StatusCheckResult - -import subprocess - -class ICMPStatusCheck(StatusCheck): - class Meta(StatusCheck.Meta): - proxy = True - - @property - def check_category(self): - return "ICMP/Ping Check" - - def _run(self): - result = StatusCheckResult(status_check=self) - instances = self.instance_set.all() - target = self.instance_set.get().address - - args = ['ping', '-c', '1', target] - try: - # We redirect stderr to STDOUT because ping can write to both, depending on the kind of error. - subprocess.check_output(args, stderr=subprocess.STDOUT, shell=False) - result.succeeded = True - except subprocess.CalledProcessError as e: - result.succeeded = False - result.error = e.output - - return result - - def __str__(self): - return self.name - - -class ICMPStatusCheckForm(StatusCheckForm): - class Meta: - model = ICMPStatusCheck - fields = ( - 'name', - 'frequency', - 'importance', - 'active', - 'debounce', - ) - widgets = dict(**base_widgets) - - -#views -class ICMPCheckCreateView(CheckCreateView): - model = ICMPStatusCheck - form_class = ICMPStatusCheckForm - - -class ICMPCheckUpdateView(CheckUpdateView): - model = ICMPStatusCheck - form_class = ICMPStatusCheckForm diff --git a/cabot/cabotapp/plugins_a_borrar/jenkins_check_plugin_delete.py b/cabot/cabotapp/plugins_a_borrar/jenkins_check_plugin_delete.py deleted file mode 100644 index d1c352a2c..000000000 --- a/cabot/cabotapp/plugins_a_borrar/jenkins_check_plugin_delete.py +++ /dev/null @@ -1,139 +0,0 @@ -import os - -from django.db import models - -from ..jenkins import get_job_status -from ..models import StatusCheck, StatusCheckResult - - -class JenkinsStatusCheck(StatusCheck): - jenkins_config = models.ForeignKey('JenkinsConfig', on_delete=models.CASCADE) - - @property - def check_category(self): - return "Jenkins check" - - @property - def failing_short_status(self): - return 'Job failing on Jenkins' - - def _run(self): - result = StatusCheckResult(status_check=self) - try: - status = get_job_status(self.jenkins_config, self.name) - active = status['active'] - result.job_number = status['job_number'] - result.consecutive_failures = status['consecutive_failures'] - if status['status_code'] == 404: - result.error = u'Job %s not found on Jenkins' % self.name - result.succeeded = False - return result - elif status['status_code'] > 400: - # Will fall through to next block - raise Exception(u'returned %s' % status['status_code']) - except Exception as e: - # If something else goes wrong, we will *not* fail - otherwise - # a lot of services seem to fail all at once. - # Ugly to do it here but... - result.error = u'Error fetching from Jenkins - %s' % e.message - result.succeeded = True - return result - - if not active: - # We will fail if the job has been disabled - result.error = u'Job "%s" disabled on Jenkins' % self.name - result.succeeded = False - else: - if self.max_queued_build_time and status['blocked_build_time']: - if status['blocked_build_time'] > self.max_queued_build_time * 60: - result.succeeded = False - result.error = u'Job "%s" has blocked build waiting for %ss (> %sm)' % ( - self.name, - int(status['blocked_build_time']), - self.max_queued_build_time, - ) - result.job_number = status['queued_job_number'] - else: - result.succeeded = status['succeeded'] - else: - result.succeeded = status['succeeded'] - if not status['succeeded']: - message = u'Job "%s" failing on Jenkins (%s)' % (self.name, status['consecutive_failures']) - if result.error: - result.error += u'; %s' % message - else: - result.error = message - result.raw_data = status - return result - - def calculate_debounced_passing(self, recent_results, debounce=0): - """ - `debounce` is the number of previous job failures we need (not including this) - to mark a search as passing or failing - Returns: - True if passing given debounce factor - False if failing - """ - last_result = recent_results[0] - if last_result.consecutive_failures == None: - return True - - return last_result.consecutive_failures <= debounce - - -class JenkinsConfig(models.Model): - name = models.CharField(max_length=30, blank=False) - jenkins_api = models.CharField(max_length=2000, blank=False) - jenkins_user = models.CharField(max_length=2000, blank=False) - jenkins_pass = models.CharField(max_length=2000, blank=False) - - def __str__(self): - return self.name - - -def create_default_jenkins_config(): - if not JenkinsConfig.objects.exists(): - if os.environ.get("JENKINS_API"): - JenkinsConfig.objects.create( - name="Default Jenkins", - jenkins_api=os.environ.get("JENKINS_API", "http://jenkins.example.com"), - jenkins_user=os.environ.get("JENKINS_USER", ""), - jenkins_pass=os.environ.get("JENKINS_PASS", ""), - ) - - - - - -class JenkinsStatusCheckForm(StatusCheckForm): - class Meta: - model = JenkinsStatusCheck - fields = ( - 'name', - 'importance', - 'debounce', - 'max_queued_build_time', - 'jenkins_config', - ) - widgets = dict(**base_widgets) - - - -#views - -class JenkinsCheckCreateView(CheckCreateView): - model = JenkinsStatusCheck - form_class = JenkinsStatusCheckForm - - def form_valid(self, form): - form.instance.frequency = 1 - return super(JenkinsCheckCreateView, self).form_valid(form) - - -class JenkinsCheckUpdateView(CheckUpdateView): - model = JenkinsStatusCheck - form_class = JenkinsStatusCheckForm - - def form_valid(self, form): - form.instance.frequency = 1 - return super(JenkinsCheckUpdateView, self).form_valid(form) diff --git a/cabot/cabotapp/plugins_a_borrar/urls_general b/cabot/cabotapp/plugins_a_borrar/urls_general deleted file mode 100644 index 2e11585ae..000000000 --- a/cabot/cabotapp/plugins_a_borrar/urls_general +++ /dev/null @@ -1,21 +0,0 @@ - ''' - url(r'^icmpcheck/create/', view=ICMPCheckCreateView.as_view(), - name='create-icmp-check'), - url(r'^icmpcheck/update/(?P\d+)/', - view=ICMPCheckUpdateView.as_view(), name='update-icmp-check'), - url(r'^icmpcheck/duplicate/(?P\d+)/', - view=duplicate_icmp_check, name='duplicate-icmp-check'), - url(r'^graphitecheck/create/', - view=GraphiteCheckCreateView.as_view(), name='create-graphite-check'), - url(r'^graphitecheck/update/(?P\d+)/', - view=GraphiteCheckUpdateView.as_view(), name='update-graphite-check'), - url(r'^graphitecheck/duplicate/(?P\d+)/', - view=duplicate_graphite_check, name='duplicate-graphite-check'), - url(r'^jenkins_check/create/', view=JenkinsCheckCreateView.as_view(), - name='create-jenkins-check'), - url(r'^jenkins_check/update/(?P\d+)/', - view=JenkinsCheckUpdateView.as_view(), name='update-jenkins-check'), - url(r'^jenkins_check/duplicate/(?P\d+)/', - view=duplicate_jenkins_check, - name='duplicate-jenkins-check'), - ''' \ No newline at end of file diff --git a/cabot/cabotapp/plugins_a_borrar/views_delete.py b/cabot/cabotapp/plugins_a_borrar/views_delete.py deleted file mode 100644 index 4b5242bfd..000000000 --- a/cabot/cabotapp/plugins_a_borrar/views_delete.py +++ /dev/null @@ -1,17 +0,0 @@ -def duplicate_icmp_check(request, pk): - pc = StatusCheck.objects.get(pk=pk) - npk = pc.duplicate() - return HttpResponseRedirect(reverse('update-icmp-check', kwargs={'pk': npk})) - - - -def duplicate_graphite_check(request, pk): - pc = StatusCheck.objects.get(pk=pk) - npk = pc.duplicate() - return HttpResponseRedirect(reverse('update-graphite-check', kwargs={'pk': npk})) - - -def duplicate_jenkins_check(request, pk): - pc = StatusCheck.objects.get(pk=pk) - npk = pc.duplicate() - return HttpResponseRedirect(reverse('update-jenkins-check', kwargs={'pk': npk})) diff --git a/docker-compose-base.yml b/docker-compose-base.yml index caffa6a9d..1cc952e53 100644 --- a/docker-compose-base.yml +++ b/docker-compose-base.yml @@ -1,10 +1,10 @@ -version: '2' +version: '3' services: base: build: . - image: cabot:web + image: t_dk command: "false" volumes: - .:/code env_file: - - conf/default.env + - conf/development.env diff --git a/docker-compose.yml b/docker-compose.yml index 255c72fa8..4742c6724 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,54 +1,72 @@ -version: '2' +version: '3' services: - web: - extends: - file: docker-compose-base.yml - service: base - env_file: - - conf/development.env - command: python manage.py runserver 0.0.0.0:5001 + db: + container_name: cabot_pg + image: postgres:alpine + restart: always + environment: + POSTGRES_USER: root + POSTGRES_PASSWORD: root + POSTGRES_DB: test_db ports: - - "5001:5001" - links: - - redis - - db + - "5432:5432" + volumes: + - datavolume:/var/lib/postgresql/data + + pgadmin: + container_name: cabot_pg_admin + image: dpage/pgadmin4 + restart: always + environment: + PGADMIN_DEFAULT_EMAIL: admin@admin.com + PGADMIN_DEFAULT_PASSWORD: root + ports: + - "5050:80" + + redis: + container_name: cabot_redis + image: redislabs/redismod + restart: always + ports: + - 6379:6379 - worker: + redisinsight: + container_name: cabot_redis_admin + image: redislabs/redisinsight:latest + restart: always + ports: + - '8001:8001' + + web: + build: . extends: file: docker-compose-base.yml service: base env_file: - conf/development.env - command: celery worker -A cabot --loglevel=DEBUG --concurrency=16 -Ofair - environment: - - SKIP_INIT=1 - - WAIT_FOR_MIGRATIONS=1 + command: python manage.py migrate + command: python manage.py runserver 0.0.0.0:8000 + ports: + - "8000:8000" links: - redis - db - beat: + worker-beat: extends: file: docker-compose-base.yml service: base env_file: - conf/development.env - command: celery beat -A cabot --loglevel=DEBUG + command: celery -A cabot worker --beat --scheduler django --loglevel=info environment: - SKIP_INIT=1 - WAIT_FOR_MIGRATIONS=1 links: - redis - db - - redis: - image: redis:alpine - - db: - image: postgres:alpine - volumes: - - datavolume:/var/lib/postgresql/data - + volumes: datavolume: + From b41fe3b569079c81943ade07ca7d5345220f41df Mon Sep 17 00:00:00 2001 From: Ladrusca Date: Fri, 6 Aug 2021 09:59:21 -0300 Subject: [PATCH 05/24] resuelto el tema enviroment y limpieza de codigo --- .coveragerc | 6 - .foreman | 4 - .gitignore | 152 ++++- .travis.yml | 24 - .vscode/launch.json | 18 + CHANGES | 272 --------- DEPRECATED_BACKUP.TXT | 11 - Dockerfile | 79 ++- Dockerfile-j | 71 +++ Pipfile | 30 - Procfile | 3 - Procfile.dev | 3 - Vagrantfile | 50 -- bin/activate | 3 - bin/activate.fish | 10 - bin/build-app | 5 - bin/test_with_coverage | 15 - cabot/cabot_config.py | 2 +- cabot/cabotapp/graphite_delete.py | 109 ---- cabot/cabotapp/jenkins_delete.py | 53 -- .../migrations/0009_auto_20210719_2116.py | 1 - cabot/celery.py | 6 +- cabot/config.py | 31 -- cabot/settings.py | 50 +- conf/default.env | 74 --- conf/development.env.example | 84 --- conf/production.env.example | 103 ---- conf/test.env | 6 - deprecated!/.coveragerc | 6 - deprecated!/.foreman | 4 - deprecated!/CHANGES | 272 --------- "deprecated!/Documento sin t\303\255tulo" | 35 -- deprecated!/MANIFEST.in | 6 - deprecated!/Pipfile | 30 - deprecated!/Procfile | 3 - deprecated!/Procfile.dev | 3 - deprecated!/Vagrantfile | 50 -- deprecated!/celerybeat-schedule.bak | 4 - deprecated!/celerybeat-schedule.dat | Bin 3728 -> 0 bytes deprecated!/celerybeat-schedule.dir | 4 - deprecated!/docker-compose-base.yml | 10 - deprecated!/docker-compose-test.yml | 13 - deprecated!/example_local_config.yml | 13 - deprecated!/get-docker.sh | 525 ------------------ deprecated!/gunicorn.conf | 7 - deprecated!/makemigrations | 4 - deprecated!/setup.cfg | 7 - deprecated!/setup_dev.sh | 3 - deprecated!/upstart/process.conf.erb | 6 - ...ker-compose.yml => docker-compose copy.yml | 4 +- docker-compose-base.yml | 4 +- docker-compose.yml | 56 +- example_local_config.yml | 13 - gunicorn.conf | 7 - makemigrations | 4 - manage.py | 4 - requirements-plugins.txt | 5 +- requirements.txt | 85 +-- setup.cfg | 7 - setup.py | 36 -- setup_dev.sh | 3 - tox.ini | 75 --- upstart/process.conf.erb | 6 - 63 files changed, 330 insertions(+), 2259 deletions(-) delete mode 100644 .coveragerc delete mode 100644 .foreman delete mode 100644 .travis.yml create mode 100644 .vscode/launch.json delete mode 100644 CHANGES delete mode 100644 DEPRECATED_BACKUP.TXT create mode 100644 Dockerfile-j delete mode 100644 Pipfile delete mode 100644 Procfile delete mode 100644 Procfile.dev delete mode 100644 Vagrantfile delete mode 100644 bin/activate delete mode 100644 bin/activate.fish delete mode 100755 bin/build-app delete mode 100755 bin/test_with_coverage delete mode 100644 cabot/cabotapp/graphite_delete.py delete mode 100644 cabot/cabotapp/jenkins_delete.py delete mode 100644 cabot/config.py delete mode 100644 conf/default.env delete mode 100644 conf/development.env.example delete mode 100644 conf/production.env.example delete mode 100644 conf/test.env delete mode 100644 deprecated!/.coveragerc delete mode 100644 deprecated!/.foreman delete mode 100644 deprecated!/CHANGES delete mode 100644 "deprecated!/Documento sin t\303\255tulo" delete mode 100644 deprecated!/MANIFEST.in delete mode 100644 deprecated!/Pipfile delete mode 100644 deprecated!/Procfile delete mode 100644 deprecated!/Procfile.dev delete mode 100644 deprecated!/Vagrantfile delete mode 100644 deprecated!/celerybeat-schedule.bak delete mode 100644 deprecated!/celerybeat-schedule.dat delete mode 100644 deprecated!/celerybeat-schedule.dir delete mode 100644 deprecated!/docker-compose-base.yml delete mode 100644 deprecated!/docker-compose-test.yml delete mode 100644 deprecated!/example_local_config.yml delete mode 100644 deprecated!/get-docker.sh delete mode 100644 deprecated!/gunicorn.conf delete mode 100755 deprecated!/makemigrations delete mode 100644 deprecated!/setup.cfg delete mode 100755 deprecated!/setup_dev.sh delete mode 100644 deprecated!/upstart/process.conf.erb rename deprecated!/docker-compose.yml => docker-compose copy.yml (95%) delete mode 100644 example_local_config.yml delete mode 100644 gunicorn.conf delete mode 100755 makemigrations delete mode 100644 setup.cfg delete mode 100644 setup.py delete mode 100755 setup_dev.sh delete mode 100644 tox.ini delete mode 100644 upstart/process.conf.erb diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index 0241cc7ad..000000000 --- a/.coveragerc +++ /dev/null @@ -1,6 +0,0 @@ -[run] -branch = True -plugins = - django_coverage_plugin - -omit = *migrations* diff --git a/.foreman b/.foreman deleted file mode 100644 index 72cf0c3b4..000000000 --- a/.foreman +++ /dev/null @@ -1,4 +0,0 @@ -# vi: set ft=yaml : - -procfile: Procfile.dev -env: conf/development.env diff --git a/.gitignore b/.gitignore index 14558ba39..acb04e66e 100644 --- a/.gitignore +++ b/.gitignore @@ -19,7 +19,155 @@ conf/*.env dist/ local_config.yml build/ - +.dockerignore .idea Pipfile.lock -.tox/ \ No newline at end of file +.tox/ + +### Python ### +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# End of https://www.toptal.com/developers/gitignore/api/python + +Dockerfile +requirements-plugins.txt +requirements-dev.txt +setup.py +Dockerfile copy \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 2474059be..000000000 --- a/.travis.yml +++ /dev/null @@ -1,24 +0,0 @@ -sudo: required -services: - - docker - -before_install: - - sudo pip install tox - -# setup databases -before_script: - - cp conf/development.env.example conf/development.env - - docker-compose build - -script: - - tox - - docker-compose -f docker-compose-test.yml run --rm --entrypoint bin/test_with_coverage test -v2 - - git checkout $(git describe --abbrev=0 --tags `git describe --tags`^) && docker-compose build web - - docker-compose run --rm web true - - git checkout - && docker-compose build web - - docker-compose run --rm web true - -after_success: - - sudo pip install codecov - - sudo pip install django_coverage_plugin==1.4.2 - - codecov diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..3453b21b8 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,18 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python: Django", + "type": "python", + "request": "launch", + "program": "${workspaceFolder}/manage.py", + "args": [ + "runserver" + ], + "django": true + } + ] +} \ No newline at end of file diff --git a/CHANGES b/CHANGES deleted file mode 100644 index a80a04b5a..000000000 --- a/CHANGES +++ /dev/null @@ -1,272 +0,0 @@ -Version 0.11.16 ---------------- - -* Upgrade celery and kombu - -Version 0.11.15 ---------------- - -* Fix dockerfile -* Add support for changing default celery queue name (using CELERY_DEFAULT_QUEUE env variable) - -Version 0.11.14 ---------------- - -* Add support for celery SQS backend - -Version 0.11.13 ---------------- - -* Fix bug where jenkins checks were always passing -* Reduce Arachnys branding a bit -* Fix 404 page for logged out users -* Style forms with django-bootstrap-form -* [[#605](https://github.com/arachnys/cabot/issues/605)] Fix http check forms auto-filling username/password -* [[#607](https://github.com/arachnys/cabot/issues/607)] Fix checks for websites service non utf-8 content - -Version 0.11.12 ---------------- - -* Upgrade django to 1.11.11 -* Debounce JenkinsCheck on the number of job failures - - Previously it would fail after cabot checked the jenkins api N times, even if the jenkins job had only failed once - -Version 0.11.11 ---------------- - -* Fix /api/oncall endpoint not working with basic auth - -Version 0.11.10 ---------------- - -* Add /api/oncall endpoint - -Version 0.11.9 --------------- - -* Fix issue where Jenkins environment variables were required on first launch - -Version 0.11.8 --------------- - -* Bump cabot-alert-slack to 0.8.2 -* Update LDAP dependencies -* Add ENABLE_SUBSCRIPTION and ENABLE_DUTY_ROTA options -* [[#556](https://github.com/arachnys/cabot/issues/556)] Fix issue with HttpStatusCheck with unicode content - -Version 0.11.7 --------------- - -* Fix check plugins not displaying checks correctly on service details page - -Version 0.11.6 --------------- - -* Add cloudwatch check plugin to dockerfile by default - - Can be enabled by adding "cabot_check_cloudwatch" to CABOT_PLUGINS_ENABLED - -Version 0.11.5 --------------- - -* Fix multiple jenkins configs not working properly - - Due to caching on the client, the first config to be checked would always be used - -Version 0.11.4 --------------- - -* Switch from jenkinsapi to python-jenkins - - Fixes performance regression introduced in 0.11 - -Version 0.11.3 --------------- - -* [[#551](https://github.com/arachnys/cabot/issues/551)] Fix in-progress jenkins jobs being marked as failing - -Version 0.11.2 --------------- - -* Fix pypi source distribution missing requirements for setup.py - -Version 0.11.1 --------------- - -* Fix migration disassociating checks from services/instances -* Fix migration requiring jenkins environment variables are set -* Reduce time to store old check results to 7 days - - Currently stores for 2 months, but there's no actual way to view the old data. - -Version 0.11.0 --------------- - -*** BROKEN RELEASE - MIGRATIONS DON'T WORK CORRECTLY *** - -* Jenkins support: - - Fail Jenkins checks when job is unknown - - Use [jenkinsapi](https://pypi.python.org/pypi/jenkinsapi) to talk to Jenkins - - Add option to specify multiple Jenkins backends - > NOTE: This update will delete any recent status check results for jenkins checks -* Add view for public services -* Add support for Google OAuth login -* Add ability to add custom check plugins - - See https://gitlab.com/as-public/cabot-check-skeleton for an example -* Remove deprecated Fabfile and Shell scripts - -Version 0.10.8 --------------- - -* Update slack alert to 0.8.1 - - fixes names not linking - - only shows the acknowledge button if "SLACK_INTERACTIVE_MESSAGES" is set - - (The feature only works if set up correctly on the slack end) -* Update to django 1.11 (with working django-polymorphic this time) - -Version 0.10.7 --------------- - -* Update slack alert plugin - - Now shows an "acknowledge" button within slack -* Fix alert tests not triggering if: - - A user had acknowledged working on the service - - A legitimate alert had been sent recently -* Add support for GitHub OAuth logins - - See http://cabotapp.com/use/users.html - -Version 0.10.6 --------------- - -* Fix plugin urls being overridden by plugin settings urls - - This fixes e.g. the twilio callback url not working -* Fix profile settings sidebar links not working - -Version 0.10.5 --------------- - -* Fix bug which caused status graphs to sometimes not render -* Fix issue with complex recurring calendar - `'vDDDLists' object is not iterable` -* Fix css regression in logo/title - -Version 0.10.4 --------------- - -* Fix basic auth passwords getting reset when editing checks -* Fix plugin alert tests alerting the current duty officer - - They should now always alert only the user that runs the test - -Version 0.10.3 --------------- - -* Add plugin settings views with the ability to test alerts. -* Allow user filter for LDAP to be configured - - Set the AUTH_LDAP_USER_FILTER setting to change it (defaults to "(uid=%(user)s)") -* Update cabot-alert-hipchat plugin to 2.0.2 - - Fixes bug when both HIPCHAT_URL and HIPCHAT_DOMAIN were set - -Version 0.10.2 --------------- - -* Update cabot-alert-hipchat plugin to 2.0.1 - - Supports Hipchat API v2 - - If HIPCHAT_URL is set, it will use the old v1 api - - Use HIPCHAT_DOMAIN for custom hipchat v2 deployments -* Add interactive api docs (using djangorestframework 3.6) at /docs - -Version 0.10.1 --------------- - -* [BUGFIX] Update cabot_alert_twilio to 1.3.1 - - 1.3.0 was still broken on django 1.10 - -Version 0.10.0 --------------- - -* Add feedback notifications when updated profile -* Automatically reload plugins after migrating -* Add cabot_alert_slack as default plugin -* Upgrade to Django 1.10 -* Upgrade to Celery 4 - -Version 0.9.2 -------------- - -* Add /about endpoint -* Fix rota bug when ical had no timezone -* Add User Profile settings link to user dropdown - -Version 0.9.1 -------------- - -* Update cabot-alert-twilio to 1.3.0 to work on django 1.10 -* Fix Alert preferences form breaking on django 1.8 -* Add `cabot` executable instead of using python manage.py (for e.g. migrating) - -Version 0.9.0 -------------- - -* Upgrade to Django 1.9 - -Version 0.8.7 -------------- - -* Fix Alert preferences form breaking on django 1.8 - -Version 0.8.6 -------------- - -* Add first time setup page -* Remove create_cabot_superuser management command (redundant with first time setup) - -Version 0.8.5 -------------- - -* More severe alerts should trigger even if a less severe alert was recently sent -* Update production.env.example email settings -* Convert environment vars to boolean nicely - -> Note: You may have to update your settings if they contain invalid boolean values - -Version 0.8.4 -------------- - -* Fix setup.py packaging -* Use whitenoise to serve static files - -> Note: You may have to update your webserver settings for static files to work properly - -Version 0.8.3 -------------- - -* BUG: Add missing context processor - -Version 0.8.2 -------------- - -* Remove django-smtp-ssl dependency -* Build docker image from alpine -* Refactor docker-compose files -* Fix db_clean task failing on large results tables -* Wait for docker containers to start in docker-entrypoint.sh -* Update CABOT_PLUGINS_ENABLED to compatible plugin versions -* Automatically initialise database, assets and superuser on docker container start - -Version 0.8.1 -------------- - -* Fix all workers running celery beat -* Update django-compressor to run on django 1.8 -* Fix typo in url testcase -* Update wsgi.py to work with django 1.8 - -Version 0.8.0 -------------- - -* Upgraded to Django 1.8 - -Version 0.7.0 -------------- - -* Upgraded to Django 1.7 - -Version 0.6.0 -------------- - -* Versioning Introduced. diff --git a/DEPRECATED_BACKUP.TXT b/DEPRECATED_BACKUP.TXT deleted file mode 100644 index 4e6672b0c..000000000 --- a/DEPRECATED_BACKUP.TXT +++ /dev/null @@ -1,11 +0,0 @@ -MIDDLEWARE= - - ''' - 'whitenoise.middleware.WhiteNoiseMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - ''' \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 3feeacd52..fa658cadd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,25 +1,31 @@ -FROM python:3.6.5-jessie - -RUN apt-get update -RUN DEBIAN_FRONTEND=noninteractive apt-get install -y \ - default-libmysqlclient-dev \ - build-essential \ - python3-dev \ - python2.7-dev \ - libldap2-dev \ - libsasl2-dev \ - slapd \ - ldap-utils \ - python-tox \ - lcov \ - valgrind\ - curl\ - python-dev \ - gcc \ - musl-dev \ - libffi-dev \ - ca-certificates \ - bash +FROM python:3.6-alpine AS builder-image + +RUN apk update && apk add --no-cache \ + postgresql-dev \ + mariadb-dev \ + py-pip \ + postgresql-dev \ + mariadb-dev \ + gcc \ + curl \ + curl-dev \ + libcurl \ + musl-dev \ + libffi-dev \ + openldap-dev \ + ca-certificates \ + cargo \ + build-base \ + python3-dev \ + musl-dev \ + libevent-dev \ + bash + +# create and activate virtual environment +# using final folder name to avoid path issues with packages +RUN python3 -m venv /home/cabot/venv +ENV PATH="/home/cabot/venv/bin:$PATH" + ENV PYTHONUNBUFFERED 1 @@ -32,14 +38,31 @@ WORKDIR /code COPY requirements.txt ./ RUN pip install --no-cache-dir -r requirements.txt -COPY requirements-dev.txt ./ -RUN pip install --no-cache-dir -r requirements-dev.txt +######################################################## +FROM python:3.6-alpine AS runner-image + +RUN adduser -S cabot +COPY --from=builder-image /home/cabot/venv /home/cabot/venv + +USER cabot +RUN mkdir /home/cabot/code +WORKDIR /home/cabot/code + +COPY cabot . +COPY manage.py ./cabot + +EXPOSE 8000 -COPY requirements-plugins.txt ./ -RUN pip install --no-cache-dir -r requirements-plugins.txt +# make sure all messages always reach console +ENV PYTHONUNBUFFERED=1 -ADD . /code/ +# activate virtual environment +ENV VIRTUAL_ENV=/home/cabot/venv +ENV PATH="/home/cabot/venv/bin:$PATH" +# /dev/shm is mapped to shared memory and should be used for gunicorn heartbeat +# this will improve performance and avoid random freezes +CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"] -ENTRYPOINT ["./docker-entrypoint.sh"] \ No newline at end of file +#ENTRYPOINT ["./docker-entrypoint.sh"] \ No newline at end of file diff --git a/Dockerfile-j b/Dockerfile-j new file mode 100644 index 000000000..5f112fad2 --- /dev/null +++ b/Dockerfile-j @@ -0,0 +1,71 @@ +FROM python:3.6.5-slim-jessie AS builder-image + +RUN apt-get update +RUN DEBIAN_FRONTEND=noninteractive apt-get install -y \ + libmysqlclient-dev \ + build-essential \ + python3-dev \ + python2.7-dev \ + libldap2-dev \ + libsasl2-dev \ + slapd \ + ldap-utils \ + python-tox \ + lcov \ + valgrind\ + curl\ + python-dev \ + gcc \ + musl-dev \ + libffi-dev \ + ca-certificates \ + git\ + bash + + +# create and activate virtual environment +# using final folder name to avoid path issues with packages +RUN python3 -m venv /home/cabot/venv +ENV PATH="/home/cabot/venv/bin:$PATH" + + +ENV PYTHONUNBUFFERED 1 + +RUN pip install --upgrade pip + +RUN mkdir /code + +WORKDIR /code + +COPY requirements.txt ./ +RUN pip install --no-cache-dir -r requirements.txt + +######################################################## +FROM python:3.6.5-slim-jessie AS runner-image + +RUN apt-get update && apt-get install --no-install-recommends -y python3-venv && \ +apt-get clean && rm -rf /var/lib/apt/lists/* + +RUN useradd --create-home cabot +COPY --from=builder-image /home/cabot/venv /home/cabot/venv + +USER cabot +RUN mkdir /home/cabot/code +WORKDIR /home/cabot/code +COPY . . + +EXPOSE 8000 + +# make sure all messages always reach console +ENV PYTHONUNBUFFERED=1 + +# activate virtual environment +ENV VIRTUAL_ENV=/home/cabot/venv +ENV PATH="/home/cabot/venv/bin:$PATH" + +# /dev/shm is mapped to shared memory and should be used for gunicorn heartbeat +# this will improve performance and avoid random freezes +CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"] + + +#ENTRYPOINT ["./docker-entrypoint.sh"] \ No newline at end of file diff --git a/Pipfile b/Pipfile deleted file mode 100644 index ff32bedfa..000000000 --- a/Pipfile +++ /dev/null @@ -1,30 +0,0 @@ -[[source]] -url = "https://pypi.python.org/simple" -verify_ssl = true - -[packages] -amqp = ">=2.1.4" -celery = ">=4,<5" -djangorestframework = "*" -django-jsonify = "*" -django-filter = "*" -django-auth-ldap = "*" -anyjson = "*" -dj-database-url = "*" -freezegun = "*" -gevent = "*" -gunicorn = "*" -icalendar = "*" -psycopg2 = "*" -python-dateutil = "*" -pytz = "*" -redis = "*" -requests = "*" -twilio = ">=5,<6" -whitenoise = "*" -coreapi = "*" -Django = ">=1.11,<2" -django_polymorphic = "*" -django_compressor = "*" -Markdown = "*" -Pygments = "*" diff --git a/Procfile b/Procfile deleted file mode 100644 index dc603d723..000000000 --- a/Procfile +++ /dev/null @@ -1,3 +0,0 @@ -web: gunicorn cabot.wsgi:application --config gunicorn.conf -celery: celery worker -A cabot --loglevel=INFO --concurrency=16 -Ofair -beat: celery beat -A cabot --loglevel=INFO diff --git a/Procfile.dev b/Procfile.dev deleted file mode 100644 index d3cecc003..000000000 --- a/Procfile.dev +++ /dev/null @@ -1,3 +0,0 @@ -web: python manage.py runserver 0.0.0.0:$PORT -celery: celery -A cabot worker --loglevel=DEBUG -c 8 -Ofair -beat: celery -A cabot beat --loglevel=DEBUG diff --git a/Vagrantfile b/Vagrantfile deleted file mode 100644 index 6c1fc0849..000000000 --- a/Vagrantfile +++ /dev/null @@ -1,50 +0,0 @@ -# -*- mode: ruby -*- -# vi: set ft=ruby : -require 'yaml' - -# Load local config overrides -local_config = File.file?("local_config.yml") ? YAML.load(File.read("local_config.yml")) : {} - -Vagrant::configure("2") do |config| - # All Vagrant configuration is done here. The most common configuration - # options are documented and commented below. For a complete reference, - # please see the online documentation at vagrantup.com. - - # Every Vagrant virtual environment requires a box to build off of. - config.vm.box = local_config["box"] || "hashicorp/precise64" - - # Virtualbox - config.vm.provider "virtualbox" do |vb| - vb.customize [ - "modifyvm", :id, - "--memory", local_config['ram'] || "1024", - "--cpus", local_config['cpu'] || 1, - "--ioapic", "on", - ] - end - - #vmware_fusion - config.vm.provider "vmware_fusion" do |v| - v.vmx["memsize"] = local_config['ram'] || "1024" - v.vmx["numvcpus"] = local_config['cpu'] || 1 - end - - # Boot with a GUI so you can see the screen. (Default is headless) - # config.vm.boot_mode = :gui - - # Assign this VM to a host-only network IP, allowing you to access it - # via the IP. Host-only networks can talk to the host machine as well as - # any other machines on the same network, but cannot be accessed (through this - # network interface) by any external networks. - config.vm.network "forwarded_port", guest: 5001, host: 5001 - - # Share an additional folder to the guest VM. The first argument is - # an identifier, the second is the path on the guest to mount the - # folder, and the third is the path on the host to the actual folder. - config.vm.synced_folder "./", "/vagrant", create: true - - # Provision the development environment - config.vm.provision :shell do |shell| - shell.inline = 'sudo /vagrant/bin/provision' - end -end diff --git a/bin/activate b/bin/activate deleted file mode 100644 index b48311853..000000000 --- a/bin/activate +++ /dev/null @@ -1,3 +0,0 @@ -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -export PATH=$PATH:$DIR/../bin:$DIR/../app -export PYTHONPATH=$PYTHONPATH:$DIR/../app diff --git a/bin/activate.fish b/bin/activate.fish deleted file mode 100644 index 3490a0849..000000000 --- a/bin/activate.fish +++ /dev/null @@ -1,10 +0,0 @@ -# fix broken locale -if not python -c 'import locale; locale.getdefaultlocale();' >/dev/null ^&1 - set -gx LANG en_US.UTF-8 - set -gx LC_ALL en_US.UTF-8 -end - -# set paths -set DIR (dirname (status -f)) -set -gx PATH $PATH $DIR/../bin $DIR/../app -set -gx PYTHONPATH $PYTHONPATH $DIR/../app diff --git a/bin/build-app b/bin/build-app deleted file mode 100755 index de2fa5470..000000000 --- a/bin/build-app +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -set -e -python manage.py migrate -python manage.py collectstatic --noinput -# python manage.py compress diff --git a/bin/test_with_coverage b/bin/test_with_coverage deleted file mode 100755 index 1313c33d3..000000000 --- a/bin/test_with_coverage +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash -set -x - -output_dir='test-results' -mkdir -p $output_dir - -./manage.py collectstatic --no-input -TEMPLATE_DEBUG=True coverage run --source="./cabot/" manage.py test $@ -status=$? - -coverage report --omit="cabot/cabotapp/tests*" -coverage xml --omit="cabot/cabotapp/tests*" -o $output_dir/coverage.xml -coverage html --omit="cabot/cabotapp/tests*" -d $output_dir/htmlcov/ - -exit $status diff --git a/cabot/cabot_config.py b/cabot/cabot_config.py index c82754e8b..e518ea4d6 100644 --- a/cabot/cabot_config.py +++ b/cabot/cabot_config.py @@ -31,4 +31,4 @@ # Default plugins are used if the user has not specified. #CABOT_PLUGINS_ENABLED = os.environ.get('CABOT_PLUGINS_ENABLED', 'cabot_alert_hipchat,cabot_alert_twilio,cabot_alert_email') -CABOT_PLUGINS_ENABLED = os.environ.get('CABOT_PLUGINS_ENABLED') \ No newline at end of file +#CABOT_PLUGINS_ENABLED = os.environ.get('CABOT_PLUGINS_ENABLED') \ No newline at end of file diff --git a/cabot/cabotapp/graphite_delete.py b/cabot/cabotapp/graphite_delete.py deleted file mode 100644 index 4b5ecb59c..000000000 --- a/cabot/cabotapp/graphite_delete.py +++ /dev/null @@ -1,109 +0,0 @@ -from django.conf import settings -import requests -import logging -import time - -graphite_api = settings.GRAPHITE_API -user = settings.GRAPHITE_USER -password = settings.GRAPHITE_PASS -graphite_from = settings.GRAPHITE_FROM -auth = (user, password) - - -def get_data(target_pattern, mins_to_check=None): - - if mins_to_check: - _from = '-%dminute' % mins_to_check - else: - _from = graphite_from - - resp = requests.get( - graphite_api + 'render', auth=auth, - params={ - 'target': target_pattern, - 'format': 'json', - 'from': _from, - } - ) - resp.raise_for_status() - return resp.json() - - -def get_matching_metrics(pattern): - print('Getting metrics matching %s' % pattern) - resp = requests.get( - graphite_api + 'metrics/find/', auth=auth, - params={ - 'query': pattern, - 'format': 'completer' - }, - headers={ - 'accept': 'application/json' - } - ) - resp.raise_for_status() - return resp.json() - - -def get_all_metrics(limit=None): - """Grabs all metrics by navigating find API recursively""" - metrics = [] - - def get_leafs_of_node(nodepath): - for obj in get_matching_metrics(nodepath)['metrics']: - if int(obj['is_leaf']) == 1: - metrics.append(obj['path']) - else: - get_leafs_of_node(obj['path']) - get_leafs_of_node('') - return metrics - - -def parse_metric(metric, mins_to_check=5, utcnow=None): - if utcnow is None: - utcnow = time.time() - ret = { - 'num_series_with_data': 0, - 'num_series_no_data': 0, - 'error': None, - 'raw': '', - 'series': [], - } - try: - data = get_data(metric, mins_to_check) - except requests.exceptions.RequestException as e: - ret['error'] = 'Error getting data from Graphite: %s' % e - ret['raw'] = ret['error'] - logging.error('Error getting data from Graphite: %s' % e) - return ret - all_values = [] - for target in data: - series = {'values': [ - float(t[0]) for t in target['datapoints'] if validate_datapoint(t, mins_to_check, utcnow)]} - series["target"] = target["target"] - all_values.extend(series['values']) - if series['values']: - ret['num_series_with_data'] += 1 - series['max'] = max(series['values']) - series['min'] = min(series['values']) - series['average_value'] = sum(series['values']) / len(series['values']) - ret['series'].append(series) - else: - ret['num_series_no_data'] += 1 - if all_values: - ret['average_value'] = sum(all_values) / len(all_values) - ret['all_values'] = all_values - ret['raw'] = data - return ret - -def validate_datapoint(datapoint, mins_to_check, utcnow): - val, timestamp = datapoint - secs_to_check = 60 * mins_to_check - if val is None: - return False - if timestamp > (utcnow - secs_to_check): - return True - else: - return False - - diff --git a/cabot/cabotapp/jenkins_delete.py b/cabot/cabotapp/jenkins_delete.py deleted file mode 100644 index 362e6ec11..000000000 --- a/cabot/cabotapp/jenkins_delete.py +++ /dev/null @@ -1,53 +0,0 @@ -from __future__ import absolute_import - -from datetime import datetime - -import jenkins -from celery.utils.log import get_task_logger -from django.conf import settings -from django.utils import timezone - -logger = get_task_logger(__name__) - - -def _get_jenkins_client(jenkins_config): - return jenkins.Jenkins(jenkins_config.jenkins_api, - username=jenkins_config.jenkins_user, - password=jenkins_config.jenkins_pass) - -def get_job_status(jenkins_config, jobname): - ret = { - 'active': None, - 'succeeded': None, - 'job_number': None, - 'blocked_build_time': None, - } - client = _get_jenkins_client(jenkins_config) - try: - job = client.get_job_info(jobname) - last_completed_build = job['lastCompletedBuild'] - if not last_completed_build: - raise Exception("job has no build") - last_build = client.get_build_info(jobname, last_completed_build['number']) - - if job['lastSuccessfulBuild']: - last_good_build_number = job['lastSuccessfulBuild']['number'] - else: - last_good_build_number = 0 - - ret['status_code'] = 200 - ret['job_number'] = last_build['number'] - ret['active'] = job['color'] != 'disabled' - ret['succeeded'] = ret['active'] and last_build['result'] == 'SUCCESS' - ret['consecutive_failures'] = last_build['number'] - last_good_build_number - - if job['inQueue']: - in_queued_since = job['queueItem']['inQueueSince'] - time_blocked_since = datetime.utcfromtimestamp( - float(in_queued_since) / 1000).replace(tzinfo=timezone.utc) - ret['blocked_build_time'] = (timezone.now() - time_blocked_since).total_seconds() - ret['queued_job_number'] = job['lastBuild']['number'] - return ret - except jenkins.NotFoundException: - ret['status_code'] = 404 - return ret diff --git a/cabot/cabotapp/migrations/0009_auto_20210719_2116.py b/cabot/cabotapp/migrations/0009_auto_20210719_2116.py index 2de644e5a..351a00123 100644 --- a/cabot/cabotapp/migrations/0009_auto_20210719_2116.py +++ b/cabot/cabotapp/migrations/0009_auto_20210719_2116.py @@ -7,7 +7,6 @@ class Migration(migrations.Migration): dependencies = [ - ('cabot_check_http', '0002_auto_20210719_2116'), ('cabotapp', '0008_auto_20210707_1645'), ] diff --git a/cabot/celery.py b/cabot/celery.py index 26ead9856..51910e09d 100644 --- a/cabot/celery.py +++ b/cabot/celery.py @@ -6,12 +6,8 @@ from django.conf import settings from celery import Celery -from .config import config_charge -config_charge() - -os.environ.setdefault('DJANGO_SETTINGS_MODULE', - 'cabot.settings') +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'cabot.settings') app = Celery('cabot') diff --git a/cabot/config.py b/cabot/config.py deleted file mode 100644 index 18d1c2c85..000000000 --- a/cabot/config.py +++ /dev/null @@ -1,31 +0,0 @@ -import os - - -def config_charge(): - config = open("conf/development.env", "r") - lines = config.read().splitlines() - config.close() - - for line in lines: - - key = '' - value = '' - divider = 0 - - if line != "": - if line[0] != "#": - - divider = line.find('=') - - key = line[:divider] - value = line[divider+1:] - - os.environ[key]=value - else: - pass - - - - - - \ No newline at end of file diff --git a/cabot/settings.py b/cabot/settings.py index ac998ab5b..9c1f0257f 100644 --- a/cabot/settings.py +++ b/cabot/settings.py @@ -1,16 +1,21 @@ import os -import dj_database_url import re from django.conf import settings from django.urls import reverse_lazy from cabot.settings_utils import environ_get_list, force_bool from cabot.cabot_config import * + + settings_dir = os.path.dirname(__file__) PROJECT_ROOT = os.path.abspath(settings_dir) -import redis +DEBUG = True +if os.environ.get('DEBUG', True)=='True': + DEBUG=True -DEBUG = os.environ.get('DEBUG') +PROD = False +if os.environ.get('PROD', True)=='True': + PROD=True ADMINS = ( ('Admin', os.environ.get('ADMIN_EMAIL', 'name@example.com')), @@ -19,16 +24,16 @@ MANAGERS = ADMINS if os.environ.get('CABOT_FROM_EMAIL'): - DEFAULT_FROM_EMAIL = os.environ['CABOT_FROM_EMAIL'] + DEFAULT_FROM_EMAIL = os.environ.get('CABOT_FROM_EMAIL', 'admin@example.com') DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': os.environ.get('DATABASE_NAME'), - 'USER': os.environ.get('DATABASE_USER'), - 'PASSWORD': os.environ.get('DATABASE_PASSWORD'), - 'HOST': os.environ.get('DATABASE_HOST'), - 'PORT': os.environ.get('DATABASE_PORT'), + 'NAME': os.environ.get('DATABASE_NAME', 'cabot'), + 'USER': os.environ.get('DATABASE_USER', 'root'), + 'PASSWORD': os.environ.get('DATABASE_PASSWORD', 'root'), + 'HOST': os.environ.get('DATABASE_HOST', '127.0.0.1'), + 'PORT': os.environ.get('DATABASE_PORT', '5432'), } } @@ -50,10 +55,10 @@ # timezone as the operating system. # If running in a Windows environment this must be set to the same as your # system time zone. -TIME_ZONE = os.environ.get('TIME_ZONE') +TIME_ZONE = os.environ.get('TIME_ZONE','America/Argentina/Buenos_Aires') # Language code for this installation. All choices can be found here: # http://www.i18nguy.com/unicode/language-identifiers.html -LANGUAGE_CODE = 'en-us' +LANGUAGE_CODE = 'es' SITE_ID = 1 @@ -101,7 +106,7 @@ 'compressor.finders.CompressorFinder', ) -if os.environ.get('WWW_SCHEME') == 'https': +if os.environ.get('WWW_SCHEME', 'http') == 'https': SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') # Make this unique, and don't share it with anybody. @@ -162,25 +167,28 @@ 'django_celery_beat', ) -CELERY_BROKER_URL = os.environ.get('CELERY_BROKER_URL') -CELERY_RESULT_BACKEND = os.environ.get('CELERY_RESULT_BACKEND') -CELERY_BEAT_SCHEDULER = os.environ.get('CELERY_BEAT_SCHEDULER') +CELERY_BROKER_URL = os.environ.get('CELERY_BROKER_URL', 'redis://redis:6379') +CELERY_RESULT_BACKEND = os.environ.get('CELERY_RESULT_BACKEND', 'redis://redis:6379') +CELERY_BEAT_SCHEDULER = os.environ.get('CELERY_BEAT_SCHEDULER', 'django_celery_beat.schedulers:DatabaseScheduler') CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler' -timezone = os.environ.get('TIME_ZONE') +timezone = os.environ.get('TIME_ZONE', 'America/Argentina/Buenos_Aires') DEFAULT_AUTO_FIELD = 'django.db.models.AutoField' AUTH_USER_MODEL = 'auth.User' # Load additional apps from configuration file CABOT_PLUGINS_ENABLED_PARSED = [] -#CABOT_PLUGINS_ENABLED = os.environ.get('CABOT_PLUGINS_ENABLED') -for plugin in CABOT_PLUGINS_ENABLED.split(","): - # Hack to clean up if versions of plugins specified - exploded = re.split(r'[<>=]+', plugin) - CABOT_PLUGINS_ENABLED_PARSED.append(exploded[0]) +#You can add plugins in 'CABOT_PLUGINS' replace None by list with plugin names +CABOT_PLUGINS = os.environ.get('CABOT_PLUGINS', None) + +if CABOT_PLUGINS != None: + for plugin in CABOT_PLUGINS.split(","): + # Hack to clean up if versions of plugins specified + exploded = re.split(r'[<>=]+', plugin) + CABOT_PLUGINS_ENABLED_PARSED.append(exploded[0]) diff --git a/conf/default.env b/conf/default.env deleted file mode 100644 index fd289b60d..000000000 --- a/conf/default.env +++ /dev/null @@ -1,74 +0,0 @@ -# Plugins to be loaded at launch -CABOT_PLUGINS_ENABLED=cabot_alert_hipchat,cabot_alert_twilio,cabot_alert_email,cabot_alert_slack - -DEBUG=t -DATABASE_URL=postgres://postgres@db:5432/postgres -DJANGO_SETTINGS_MODULE=cabot.settings -LOG_FILE=/dev/null -PORT=5001 - -# You shouldn't need to change anything above this line - -# Base path to include before generated URLs. If not defined, uses `/` -# URL_PREFIX=/ - -# Local time zone for this installation. Choices can be found here: -# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name -TIME_ZONE=Etc/UTC - -# URL of calendar to synchronise rota with -CALENDAR_ICAL_URL=http://www.google.com/calendar/ical/example.ics - -# Django settings -CELERY_BROKER_URL=redis://redis:6379/1 - -# From parameter for the graphite request. If not defined, by default take -10 minutes -# GRAPHITE_FROM=-10minute - -# User-Agent string used for HTTP checks -HTTP_USER_AGENT=Cabot - -# Used for pointing links back in alerts etc. -WWW_HTTP_HOST=localhost -WWW_SCHEME=http - -# OPTIONAL SETTINGS -# -# # Django admin email -# ADMIN_EMAIL=you@example.com -# CABOT_FROM_EMAIL=cabot@example.com -# -# DJANGO_SECRET_KEY= -# -# Hostname of your Graphite server instance -GRAPHITE_API=http://graphite.example.com/ -GRAPHITE_USER=username -GRAPHITE_PASS=password - -# Hipchat integration -HIPCHAT_ALERT_ROOM=room_name_or_id -HIPCHAT_API_KEY=your_hipchat_api_key - -# Jenkins integration -JENKINS_API=https://jenkins.example.com/ -JENKINS_USER=username -JENKINS_PASS=password - -# SMTP settings -SES_HOST=email-smtp.us-east-1.amazonaws.com -SES_USER=username -SES_PASS=password -SES_PORT=465 - -# Twilio integration for SMS and telephone alerts -TWILIO_ACCOUNT_SID=your_account_sid -TWILIO_AUTH_TOKEN=your_auth_token -TWILIO_OUTGOING_NUMBER=+14155551234 - -# Use for LDAP authentication -# AUTH_LDAP=true -# AUTH_LDAP_SERVER_URI=ldap://ldap.example.com -# AUTH_LDAP_BIND_DN="cn=Manager,dc=example,dc=com" -# AUTH_LDAP_BIND_PASSWORD="" -# AUTH_LDAP_USER_FILTER="(uid=%(user)s)" -# AUTH_LDAP_USER_SEARCH="ou=People,dc=example,dc=com" diff --git a/conf/development.env.example b/conf/development.env.example deleted file mode 100644 index 8a823bd09..000000000 --- a/conf/development.env.example +++ /dev/null @@ -1,84 +0,0 @@ -# Plugins to be loaded at launch -# CABOT_PLUGINS_ENABLED=cabot_alert_hipchat,cabot_alert_twilio,cabot_alert_email,cabot_alert_slack - -DEBUG=t -DATABASE_URL=postgres://postgres@db:5432/postgres -DJANGO_SETTINGS_MODULE=cabot.settings -LOG_FILE=/dev/null -PORT=5001 - -# You shouldn't need to change anything above this line - -# Base path to include before generated URLs. If not defined, uses `/` -# URL_PREFIX=/ - -# Local time zone for this installation. Choices can be found here: -# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name -TIME_ZONE=Etc/UTC - -# Django admin email -ADMIN_EMAIL=you@example.com -CABOT_FROM_EMAIL=cabot@example.com - -# URL of calendar to synchronise rota with -CALENDAR_ICAL_URL=http://www.google.com/calendar/ical/example.ics - -# Django settings -CELERY_BROKER_URL=redis://redis:6379/1 -DJANGO_SECRET_KEY=2FL6ORhHwr5eX34pP9mMugnIOd3jzVuT45f7w430Mt5PnEwbcJgma0q8zUXNZ68A - -# Hostname of your Graphite server instance -GRAPHITE_API=http://graphite.example.com/ -GRAPHITE_USER=username -GRAPHITE_PASS=password - -# From parameter for the graphite request. If not defined, by default take -10 minutes -# GRAPHITE_FROM=-10minute - -# User-Agent string used for HTTP checks -HTTP_USER_AGENT=Cabot - -# Hipchat integration -HIPCHAT_ALERT_ROOM=room_name_or_id -HIPCHAT_API_KEY=your_hipchat_api_key - -# Jenkins integration -JENKINS_API=https://jenkins.example.com/ -JENKINS_USER=username -JENKINS_PASS=password - -# SMTP settings -EMAIL_BACKEND=django.core.mail.backends.console.EmailBackend - -# Twilio integration for SMS and telephone alerts -TWILIO_ACCOUNT_SID=your_account_sid -TWILIO_AUTH_TOKEN=your_auth_token -TWILIO_OUTGOING_NUMBER=+14155551234 - -# Used for pointing links back in alerts etc. -WWW_HTTP_HOST=localhost -WWW_SCHEME=http - -# Use for LDAP authentication -# AUTH_LDAP=true -# AUTH_LDAP_SERVER_URI=ldap://ldap.example.com -# AUTH_LDAP_BIND_DN="cn=Manager,dc=example,dc=com" -# AUTH_LDAP_BIND_PASSWORD="" -# AUTH_LDAP_USER_FILTER="(uid=%(user)s)" -# AUTH_LDAP_USER_SEARCH="ou=People,dc=example,dc=com" - -# Use Github Organization for Authentication -# LOGIN_URL=/login/github-org/ -# AUTH_GITHUB_ORG=True -# AUTH_GITHUB_ORG_CLIENT_ID=2l34k5j43tb46l2kj234 -# AUTH_GITHUB_ORG_CLIENT_SECRET=23l4k5j43l6k546lk5n4kl64j2j3l5k4jjlkj2345 -# AUTH_GITHUB_ORG_NAME=myorganization - -# Use Github Enterprise Organization for Authentication -# LOGIN_URL=/login/github-enterprise-org/ -# GITHUB_ENTERPRISE_ORG_AUTH=True -# GITHUB_ENTERPRISE_ORG_URL=https://mygithubenterprise.com/ -# GITHUB_ENTERPRISE_ORG_API_URL=https://mygithubenterprise.com/api/v3/ -# GITHUB_ENTERPRISE_ORG_KEY=alskdjflkj5lk123j345l3 -# GITHUB_ENTERPRISE_ORG_SECRET=alskjdflkasjdflqkj5lkntrk13j45lk3451453245 -# GITHUB_ENTERPRISE_ORG_NAME=myorganization diff --git a/conf/production.env.example b/conf/production.env.example deleted file mode 100644 index a092faa84..000000000 --- a/conf/production.env.example +++ /dev/null @@ -1,103 +0,0 @@ -## Cabot UI URL setup -# Base path to include before generated URLs. If not defined, uses `/` -# URL_PREFIX=/ - -# Used for pointing links back in alerts etc. -WWW_HTTP_HOST=cabot.example.com -# Probable values: http, https -WWW_SCHEME=http - -## Local time zone for this installation. Choices can be found here: -# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name -TIME_ZONE=Etc/UTC - -## URL of calendar to synchronise rota with -CALENDAR_ICAL_URL=http://www.google.com/calendar/ical/example.ics - -## Django admin email, 'from' address for email alerts -ADMIN_EMAIL=you@example.com -CABOT_FROM_EMAIL=noreply@example.com - -## Django settings -CELERY_BROKER_URL=redis://:yourredispassword@localhost:6379/1 -# Create a random string of mixed case alphanumeric characters, > 40 chars. -# https://www.browserling.com/tools/random-string is a site that can do this -DJANGO_SECRET_KEY=CREATE_A_KEY - -## Graphite server settings -# Hostname of your Graphite server instance (including trailing slash) -GRAPHITE_API=http://graphite.example.com/ -GRAPHITE_USER=username -GRAPHITE_PASS=password - -# Graphite stats are evaluated through a time period to identify transient -# failures. This setting determines how many minutes back a test should -# evaluate. -# If not defined, evaluate 'now through 10 minutes ago' (-10minute) -# GRAPHITE_FROM=-10minute - -## User-Agent string used for Cabot HTTP checks -HTTP_USER_AGENT=Cabot - -## Email plugin integration -EMAIL_HOST=smtp.example.com -# SMTP authentication settings. To disable SMTP authentication, comment out -# both EMAIL_USER and EMAIL_PASSWORD. -EMAIL_USER=smtp_username -EMAIL_PASSWORD=smtp_password - -# Typical SMTP port 587 configuration -EMAIL_PORT=587 -EMAIL_USE_TLS=1 -EMAIL_USE_SSL=0 - -# Typical SMTP port 25 configuration (with no SSL/TLS) -# EMAIL_PORT=587 -# EMAIL_USE_TLS=0 -# EMAIL_USE_SSL=0 - -## Hipchat plugin integration -HIPCHAT_ALERT_ROOM=room_name_or_id -HIPCHAT_API_KEY=your_hipchat_api_key - -## SLACK -SLACK_ALERT_CHANNEL=channel_name -SLACK_WEBHOOK_URL=https://hooks.slack.com/services/XXXXXX/YYYYYY/ZZZZZZ -# SLACK_INTERACTIVE_MESSAGE=True # uncomment if you have cabot added as an app with interactive messages enabled - -## Twilio plugin integration (for SMS and telephone alerts) -TWILIO_ACCOUNT_SID=your_account_sid -TWILIO_AUTH_TOKEN=your_auth_token -TWILIO_OUTGOING_NUMBER=+14155551234 - -## Jenkins integration -JENKINS_API=https://jenkins.example.com/ -JENKINS_USER=username -JENKINS_PASS=password - -## Use for LDAP authentication -AUTH_LDAP=true -AUTH_LDAP_SERVER_URI=ldap://ldap.example.com -AUTH_LDAP_BIND_DN="cn=Manager,dc=example,dc=com" -AUTH_LDAP_BIND_PASSWORD="" -AUTH_LDAP_USER_FILTER="(uid=%(user)s)" -AUTH_LDAP_USER_SEARCH="ou=People,dc=example,dc=com" - -########################################################################### -## You shouldn't need to change anything below this line # -########################################################################### - -## Plugins to be loaded at launch -# CABOT_PLUGINS_ENABLED=cabot_alert_email,cabot_alert_hipchat,cabot_alert_twilio,cabot_alert_slack - -## Database settings -DATABASE_URL=postgres://cabot:cabot@localhost:5432/index -DJANGO_SETTINGS_MODULE=cabot.settings - -DEBUG=False -LOG_FILE=/dev/null - -## Cabot localhost operating port (point a reverse proxy to here or use Caddy) -PORT=5000 - -VENV=/home/ubuntu/venv diff --git a/conf/test.env b/conf/test.env deleted file mode 100644 index d43cc7f0b..000000000 --- a/conf/test.env +++ /dev/null @@ -1,6 +0,0 @@ -DATABASE_URL=sqlite://:memory: - -CELERY_BROKER_URL=memory:// -CELERY_ALWAYS_EAGER=True - -SKIP_INIT=True diff --git a/deprecated!/.coveragerc b/deprecated!/.coveragerc deleted file mode 100644 index 0241cc7ad..000000000 --- a/deprecated!/.coveragerc +++ /dev/null @@ -1,6 +0,0 @@ -[run] -branch = True -plugins = - django_coverage_plugin - -omit = *migrations* diff --git a/deprecated!/.foreman b/deprecated!/.foreman deleted file mode 100644 index f8e5e002a..000000000 --- a/deprecated!/.foreman +++ /dev/null @@ -1,4 +0,0 @@ -# vi: set ft=yaml : - -procfile: Procfile.dev -env: conf/production.env diff --git a/deprecated!/CHANGES b/deprecated!/CHANGES deleted file mode 100644 index a80a04b5a..000000000 --- a/deprecated!/CHANGES +++ /dev/null @@ -1,272 +0,0 @@ -Version 0.11.16 ---------------- - -* Upgrade celery and kombu - -Version 0.11.15 ---------------- - -* Fix dockerfile -* Add support for changing default celery queue name (using CELERY_DEFAULT_QUEUE env variable) - -Version 0.11.14 ---------------- - -* Add support for celery SQS backend - -Version 0.11.13 ---------------- - -* Fix bug where jenkins checks were always passing -* Reduce Arachnys branding a bit -* Fix 404 page for logged out users -* Style forms with django-bootstrap-form -* [[#605](https://github.com/arachnys/cabot/issues/605)] Fix http check forms auto-filling username/password -* [[#607](https://github.com/arachnys/cabot/issues/607)] Fix checks for websites service non utf-8 content - -Version 0.11.12 ---------------- - -* Upgrade django to 1.11.11 -* Debounce JenkinsCheck on the number of job failures - - Previously it would fail after cabot checked the jenkins api N times, even if the jenkins job had only failed once - -Version 0.11.11 ---------------- - -* Fix /api/oncall endpoint not working with basic auth - -Version 0.11.10 ---------------- - -* Add /api/oncall endpoint - -Version 0.11.9 --------------- - -* Fix issue where Jenkins environment variables were required on first launch - -Version 0.11.8 --------------- - -* Bump cabot-alert-slack to 0.8.2 -* Update LDAP dependencies -* Add ENABLE_SUBSCRIPTION and ENABLE_DUTY_ROTA options -* [[#556](https://github.com/arachnys/cabot/issues/556)] Fix issue with HttpStatusCheck with unicode content - -Version 0.11.7 --------------- - -* Fix check plugins not displaying checks correctly on service details page - -Version 0.11.6 --------------- - -* Add cloudwatch check plugin to dockerfile by default - - Can be enabled by adding "cabot_check_cloudwatch" to CABOT_PLUGINS_ENABLED - -Version 0.11.5 --------------- - -* Fix multiple jenkins configs not working properly - - Due to caching on the client, the first config to be checked would always be used - -Version 0.11.4 --------------- - -* Switch from jenkinsapi to python-jenkins - - Fixes performance regression introduced in 0.11 - -Version 0.11.3 --------------- - -* [[#551](https://github.com/arachnys/cabot/issues/551)] Fix in-progress jenkins jobs being marked as failing - -Version 0.11.2 --------------- - -* Fix pypi source distribution missing requirements for setup.py - -Version 0.11.1 --------------- - -* Fix migration disassociating checks from services/instances -* Fix migration requiring jenkins environment variables are set -* Reduce time to store old check results to 7 days - - Currently stores for 2 months, but there's no actual way to view the old data. - -Version 0.11.0 --------------- - -*** BROKEN RELEASE - MIGRATIONS DON'T WORK CORRECTLY *** - -* Jenkins support: - - Fail Jenkins checks when job is unknown - - Use [jenkinsapi](https://pypi.python.org/pypi/jenkinsapi) to talk to Jenkins - - Add option to specify multiple Jenkins backends - > NOTE: This update will delete any recent status check results for jenkins checks -* Add view for public services -* Add support for Google OAuth login -* Add ability to add custom check plugins - - See https://gitlab.com/as-public/cabot-check-skeleton for an example -* Remove deprecated Fabfile and Shell scripts - -Version 0.10.8 --------------- - -* Update slack alert to 0.8.1 - - fixes names not linking - - only shows the acknowledge button if "SLACK_INTERACTIVE_MESSAGES" is set - - (The feature only works if set up correctly on the slack end) -* Update to django 1.11 (with working django-polymorphic this time) - -Version 0.10.7 --------------- - -* Update slack alert plugin - - Now shows an "acknowledge" button within slack -* Fix alert tests not triggering if: - - A user had acknowledged working on the service - - A legitimate alert had been sent recently -* Add support for GitHub OAuth logins - - See http://cabotapp.com/use/users.html - -Version 0.10.6 --------------- - -* Fix plugin urls being overridden by plugin settings urls - - This fixes e.g. the twilio callback url not working -* Fix profile settings sidebar links not working - -Version 0.10.5 --------------- - -* Fix bug which caused status graphs to sometimes not render -* Fix issue with complex recurring calendar - `'vDDDLists' object is not iterable` -* Fix css regression in logo/title - -Version 0.10.4 --------------- - -* Fix basic auth passwords getting reset when editing checks -* Fix plugin alert tests alerting the current duty officer - - They should now always alert only the user that runs the test - -Version 0.10.3 --------------- - -* Add plugin settings views with the ability to test alerts. -* Allow user filter for LDAP to be configured - - Set the AUTH_LDAP_USER_FILTER setting to change it (defaults to "(uid=%(user)s)") -* Update cabot-alert-hipchat plugin to 2.0.2 - - Fixes bug when both HIPCHAT_URL and HIPCHAT_DOMAIN were set - -Version 0.10.2 --------------- - -* Update cabot-alert-hipchat plugin to 2.0.1 - - Supports Hipchat API v2 - - If HIPCHAT_URL is set, it will use the old v1 api - - Use HIPCHAT_DOMAIN for custom hipchat v2 deployments -* Add interactive api docs (using djangorestframework 3.6) at /docs - -Version 0.10.1 --------------- - -* [BUGFIX] Update cabot_alert_twilio to 1.3.1 - - 1.3.0 was still broken on django 1.10 - -Version 0.10.0 --------------- - -* Add feedback notifications when updated profile -* Automatically reload plugins after migrating -* Add cabot_alert_slack as default plugin -* Upgrade to Django 1.10 -* Upgrade to Celery 4 - -Version 0.9.2 -------------- - -* Add /about endpoint -* Fix rota bug when ical had no timezone -* Add User Profile settings link to user dropdown - -Version 0.9.1 -------------- - -* Update cabot-alert-twilio to 1.3.0 to work on django 1.10 -* Fix Alert preferences form breaking on django 1.8 -* Add `cabot` executable instead of using python manage.py (for e.g. migrating) - -Version 0.9.0 -------------- - -* Upgrade to Django 1.9 - -Version 0.8.7 -------------- - -* Fix Alert preferences form breaking on django 1.8 - -Version 0.8.6 -------------- - -* Add first time setup page -* Remove create_cabot_superuser management command (redundant with first time setup) - -Version 0.8.5 -------------- - -* More severe alerts should trigger even if a less severe alert was recently sent -* Update production.env.example email settings -* Convert environment vars to boolean nicely - -> Note: You may have to update your settings if they contain invalid boolean values - -Version 0.8.4 -------------- - -* Fix setup.py packaging -* Use whitenoise to serve static files - -> Note: You may have to update your webserver settings for static files to work properly - -Version 0.8.3 -------------- - -* BUG: Add missing context processor - -Version 0.8.2 -------------- - -* Remove django-smtp-ssl dependency -* Build docker image from alpine -* Refactor docker-compose files -* Fix db_clean task failing on large results tables -* Wait for docker containers to start in docker-entrypoint.sh -* Update CABOT_PLUGINS_ENABLED to compatible plugin versions -* Automatically initialise database, assets and superuser on docker container start - -Version 0.8.1 -------------- - -* Fix all workers running celery beat -* Update django-compressor to run on django 1.8 -* Fix typo in url testcase -* Update wsgi.py to work with django 1.8 - -Version 0.8.0 -------------- - -* Upgraded to Django 1.8 - -Version 0.7.0 -------------- - -* Upgraded to Django 1.7 - -Version 0.6.0 -------------- - -* Versioning Introduced. diff --git "a/deprecated!/Documento sin t\303\255tulo" "b/deprecated!/Documento sin t\303\255tulo" deleted file mode 100644 index 84aad555e..000000000 --- "a/deprecated!/Documento sin t\303\255tulo" +++ /dev/null @@ -1,35 +0,0 @@ - web: - build: . - extends: - file: docker-compose-base.yml - service: base - env_file: - - conf/development.env - command: python manage.py runserver 0.0.0.0:8000 - ports: - - "8000:8000" - links: - - redis - - db - - worker-beat: - extends: - file: docker-compose-base.yml - service: base - env_file: - - conf/development.env - command: celery -A cabot worker --beat --scheduler django --loglevel=info - environment: - - SKIP_INIT=1 - - WAIT_FOR_MIGRATIONS=1 - links: - - redis - - db - - - - - -ENTRYPOINT ["./docker-entrypoint.sh"] - - diff --git a/deprecated!/MANIFEST.in b/deprecated!/MANIFEST.in deleted file mode 100644 index d46b60e18..000000000 --- a/deprecated!/MANIFEST.in +++ /dev/null @@ -1,6 +0,0 @@ -recursive-include cabot/.collectstatic * -recursive-include cabot/templates * -include requirements.txt -include requirements-plugins.txt -include requirements-dev.txt -include README.md diff --git a/deprecated!/Pipfile b/deprecated!/Pipfile deleted file mode 100644 index ff32bedfa..000000000 --- a/deprecated!/Pipfile +++ /dev/null @@ -1,30 +0,0 @@ -[[source]] -url = "https://pypi.python.org/simple" -verify_ssl = true - -[packages] -amqp = ">=2.1.4" -celery = ">=4,<5" -djangorestframework = "*" -django-jsonify = "*" -django-filter = "*" -django-auth-ldap = "*" -anyjson = "*" -dj-database-url = "*" -freezegun = "*" -gevent = "*" -gunicorn = "*" -icalendar = "*" -psycopg2 = "*" -python-dateutil = "*" -pytz = "*" -redis = "*" -requests = "*" -twilio = ">=5,<6" -whitenoise = "*" -coreapi = "*" -Django = ">=1.11,<2" -django_polymorphic = "*" -django_compressor = "*" -Markdown = "*" -Pygments = "*" diff --git a/deprecated!/Procfile b/deprecated!/Procfile deleted file mode 100644 index dc603d723..000000000 --- a/deprecated!/Procfile +++ /dev/null @@ -1,3 +0,0 @@ -web: gunicorn cabot.wsgi:application --config gunicorn.conf -celery: celery worker -A cabot --loglevel=INFO --concurrency=16 -Ofair -beat: celery beat -A cabot --loglevel=INFO diff --git a/deprecated!/Procfile.dev b/deprecated!/Procfile.dev deleted file mode 100644 index d3cecc003..000000000 --- a/deprecated!/Procfile.dev +++ /dev/null @@ -1,3 +0,0 @@ -web: python manage.py runserver 0.0.0.0:$PORT -celery: celery -A cabot worker --loglevel=DEBUG -c 8 -Ofair -beat: celery -A cabot beat --loglevel=DEBUG diff --git a/deprecated!/Vagrantfile b/deprecated!/Vagrantfile deleted file mode 100644 index 6c1fc0849..000000000 --- a/deprecated!/Vagrantfile +++ /dev/null @@ -1,50 +0,0 @@ -# -*- mode: ruby -*- -# vi: set ft=ruby : -require 'yaml' - -# Load local config overrides -local_config = File.file?("local_config.yml") ? YAML.load(File.read("local_config.yml")) : {} - -Vagrant::configure("2") do |config| - # All Vagrant configuration is done here. The most common configuration - # options are documented and commented below. For a complete reference, - # please see the online documentation at vagrantup.com. - - # Every Vagrant virtual environment requires a box to build off of. - config.vm.box = local_config["box"] || "hashicorp/precise64" - - # Virtualbox - config.vm.provider "virtualbox" do |vb| - vb.customize [ - "modifyvm", :id, - "--memory", local_config['ram'] || "1024", - "--cpus", local_config['cpu'] || 1, - "--ioapic", "on", - ] - end - - #vmware_fusion - config.vm.provider "vmware_fusion" do |v| - v.vmx["memsize"] = local_config['ram'] || "1024" - v.vmx["numvcpus"] = local_config['cpu'] || 1 - end - - # Boot with a GUI so you can see the screen. (Default is headless) - # config.vm.boot_mode = :gui - - # Assign this VM to a host-only network IP, allowing you to access it - # via the IP. Host-only networks can talk to the host machine as well as - # any other machines on the same network, but cannot be accessed (through this - # network interface) by any external networks. - config.vm.network "forwarded_port", guest: 5001, host: 5001 - - # Share an additional folder to the guest VM. The first argument is - # an identifier, the second is the path on the guest to mount the - # folder, and the third is the path on the host to the actual folder. - config.vm.synced_folder "./", "/vagrant", create: true - - # Provision the development environment - config.vm.provision :shell do |shell| - shell.inline = 'sudo /vagrant/bin/provision' - end -end diff --git a/deprecated!/celerybeat-schedule.bak b/deprecated!/celerybeat-schedule.bak deleted file mode 100644 index 1428527ab..000000000 --- a/deprecated!/celerybeat-schedule.bak +++ /dev/null @@ -1,4 +0,0 @@ -'entries', (3072, 656) -'__version__', (512, 15) -'tz', (1024, 13) -'utc_enabled', (1536, 4) diff --git a/deprecated!/celerybeat-schedule.dat b/deprecated!/celerybeat-schedule.dat deleted file mode 100644 index ddfc9e86007b4497da74945d5abc65443f668417..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3728 zcmeHI%Wl&^6m>|_B$Fn6h4L)WltXs*J~oo9i~j&OnFVpVaNlddY&t*Ua2 zOB|QqJUPY{j;pkV1s~T0u5;Ybl9EUsamlJ-QIaoe3x6UHfI0#5r)b||Nz&frxE0by zh?r<^bKH@%1&$)oF8f#!Smh|4CA2Cxq0;PUR$-Ct7q}}a);QMB)M}%z)xA)wa;R0s zp(${m{M& zUO5S*hk>Gl+Cx}l)9KaZyCUMhwucF74^(nVj?|!%>o*Dp_A{_-K9=1S1_OC-FPV@o lnB>Sv7i9mZ|AP!Z4c-3%?YH0juT&5Ing1ol`!B=x|97?(l`Q}O diff --git a/deprecated!/celerybeat-schedule.dir b/deprecated!/celerybeat-schedule.dir deleted file mode 100644 index 1428527ab..000000000 --- a/deprecated!/celerybeat-schedule.dir +++ /dev/null @@ -1,4 +0,0 @@ -'entries', (3072, 656) -'__version__', (512, 15) -'tz', (1024, 13) -'utc_enabled', (1536, 4) diff --git a/deprecated!/docker-compose-base.yml b/deprecated!/docker-compose-base.yml deleted file mode 100644 index 1cc952e53..000000000 --- a/deprecated!/docker-compose-base.yml +++ /dev/null @@ -1,10 +0,0 @@ -version: '3' -services: - base: - build: . - image: t_dk - command: "false" - volumes: - - .:/code - env_file: - - conf/development.env diff --git a/deprecated!/docker-compose-test.yml b/deprecated!/docker-compose-test.yml deleted file mode 100644 index d2c00a737..000000000 --- a/deprecated!/docker-compose-test.yml +++ /dev/null @@ -1,13 +0,0 @@ -version: '2' -services: - test: - extends: - file: docker-compose-base.yml - service: base - entrypoint: /usr/bin/python - command: manage.py test -v2 - env_file: - - conf/test.env - sut: - image: ubuntu - command: "true" diff --git a/deprecated!/example_local_config.yml b/deprecated!/example_local_config.yml deleted file mode 100644 index b1081c5df..000000000 --- a/deprecated!/example_local_config.yml +++ /dev/null @@ -1,13 +0,0 @@ ---- -# Example Local Vagrant config -# With this file, you can override the amount of RAM and CPUs allocated -# to the VM, as well as change the base box it uses. Just copy it to -# local_config.yml and edit with whatever values you want. -# -# Note that it doesn't take effect until you vagrant destroy && vagrant up - -# double your pleasure double your CPU and RAM -ram: 2048 -cpu: 2 -# hashicorp ubuntu doesn't support VMWare, so use box-cutter -box: box-cutter/ubuntu1404 diff --git a/deprecated!/get-docker.sh b/deprecated!/get-docker.sh deleted file mode 100644 index 3022001e4..000000000 --- a/deprecated!/get-docker.sh +++ /dev/null @@ -1,525 +0,0 @@ -#!/bin/sh -set -e -# Docker CE for Linux installation script -# -# See https://docs.docker.com/engine/install/ for the installation steps. -# -# This script is meant for quick & easy install via: -# $ curl -fsSL https://get.docker.com -o get-docker.sh -# $ sh get-docker.sh -# -# For test builds (ie. release candidates): -# $ curl -fsSL https://test.docker.com -o test-docker.sh -# $ sh test-docker.sh -# -# NOTE: Make sure to verify the contents of the script -# you downloaded matches the contents of install.sh -# located at https://github.com/docker/docker-install -# before executing. -# -# Git commit from https://github.com/docker/docker-install when -# the script was uploaded (Should only be modified by upload job): -SCRIPT_COMMIT_SHA="7cae5f8b0decc17d6571f9f52eb840fbc13b2737" - - -# The channel to install from: -# * nightly -# * test -# * stable -# * edge (deprecated) -DEFAULT_CHANNEL_VALUE="stable" -if [ -z "$CHANNEL" ]; then - CHANNEL=$DEFAULT_CHANNEL_VALUE -fi - -DEFAULT_DOWNLOAD_URL="https://download.docker.com" -if [ -z "$DOWNLOAD_URL" ]; then - DOWNLOAD_URL=$DEFAULT_DOWNLOAD_URL -fi - -DEFAULT_REPO_FILE="docker-ce.repo" -if [ -z "$REPO_FILE" ]; then - REPO_FILE="$DEFAULT_REPO_FILE" -fi - -mirror='' -DRY_RUN=${DRY_RUN:-} -while [ $# -gt 0 ]; do - case "$1" in - --mirror) - mirror="$2" - shift - ;; - --dry-run) - DRY_RUN=1 - ;; - --*) - echo "Illegal option $1" - ;; - esac - shift $(( $# > 0 ? 1 : 0 )) -done - -case "$mirror" in - Aliyun) - DOWNLOAD_URL="https://mirrors.aliyun.com/docker-ce" - ;; - AzureChinaCloud) - DOWNLOAD_URL="https://mirror.azure.cn/docker-ce" - ;; -esac - -# docker-ce-rootless-extras is packaged since Docker 20.10.0 -has_rootless_extras="1" -if echo "$VERSION" | grep -q '^1'; then - has_rootless_extras= -fi - -command_exists() { - command -v "$@" > /dev/null 2>&1 -} - -is_dry_run() { - if [ -z "$DRY_RUN" ]; then - return 1 - else - return 0 - fi -} - -is_wsl() { - case "$(uname -r)" in - *microsoft* ) true ;; # WSL 2 - *Microsoft* ) true ;; # WSL 1 - * ) false;; - esac -} - -is_darwin() { - case "$(uname -s)" in - *darwin* ) true ;; - *Darwin* ) true ;; - * ) false;; - esac -} - -deprecation_notice() { - distro=$1 - date=$2 - echo - echo "DEPRECATION WARNING:" - echo " The distribution, $distro, will no longer be supported in this script as of $date." - echo " If you feel this is a mistake please submit an issue at https://github.com/docker/docker-install/issues/new" - echo - sleep 10 -} - -get_distribution() { - lsb_dist="" - # Every system that we officially support has /etc/os-release - if [ -r /etc/os-release ]; then - lsb_dist="$(. /etc/os-release && echo "$ID")" - fi - # Returning an empty string here should be alright since the - # case statements don't act unless you provide an actual value - echo "$lsb_dist" -} - -add_debian_backport_repo() { - debian_version="$1" - backports="deb http://ftp.debian.org/debian $debian_version-backports main" - if ! grep -Fxq "$backports" /etc/apt/sources.list; then - (set -x; $sh_c "echo \"$backports\" >> /etc/apt/sources.list") - fi -} - -echo_docker_as_nonroot() { - if is_dry_run; then - return - fi - if command_exists docker && [ -e /var/run/docker.sock ]; then - ( - set -x - $sh_c 'docker version' - ) || true - fi - - # intentionally mixed spaces and tabs here -- tabs are stripped by "<<-EOF", spaces are kept in the output - echo - echo "================================================================================" - echo - if [ -n "$has_rootless_extras" ]; then - echo "To run Docker as a non-privileged user, consider setting up the" - echo "Docker daemon in rootless mode for your user:" - echo - echo " dockerd-rootless-setuptool.sh install" - echo - echo "Visit https://docs.docker.com/go/rootless/ to learn about rootless mode." - echo - fi - echo - echo "To run the Docker daemon as a fully privileged service, but granting non-root" - echo "users access, refer to https://docs.docker.com/go/daemon-access/" - echo - echo "WARNING: Access to the remote API on a privileged Docker daemon is equivalent" - echo " to root access on the host. Refer to the 'Docker daemon attack surface'" - echo " documentation for details: https://docs.docker.com/go/attack-surface/" - echo - echo "================================================================================" - echo -} - -# Check if this is a forked Linux distro -check_forked() { - - # Check for lsb_release command existence, it usually exists in forked distros - if command_exists lsb_release; then - # Check if the `-u` option is supported - set +e - lsb_release -a -u > /dev/null 2>&1 - lsb_release_exit_code=$? - set -e - - # Check if the command has exited successfully, it means we're in a forked distro - if [ "$lsb_release_exit_code" = "0" ]; then - # Print info about current distro - cat <<-EOF - You're using '$lsb_dist' version '$dist_version'. - EOF - - # Get the upstream release info - lsb_dist=$(lsb_release -a -u 2>&1 | tr '[:upper:]' '[:lower:]' | grep -E 'id' | cut -d ':' -f 2 | tr -d '[:space:]') - dist_version=$(lsb_release -a -u 2>&1 | tr '[:upper:]' '[:lower:]' | grep -E 'codename' | cut -d ':' -f 2 | tr -d '[:space:]') - - # Print info about upstream distro - cat <<-EOF - Upstream release is '$lsb_dist' version '$dist_version'. - EOF - else - if [ -r /etc/debian_version ] && [ "$lsb_dist" != "ubuntu" ] && [ "$lsb_dist" != "raspbian" ]; then - if [ "$lsb_dist" = "osmc" ]; then - # OSMC runs Raspbian - lsb_dist=raspbian - else - # We're Debian and don't even know it! - lsb_dist=debian - fi - dist_version="$(sed 's/\/.*//' /etc/debian_version | sed 's/\..*//')" - case "$dist_version" in - 10) - dist_version="buster" - ;; - 9) - dist_version="stretch" - ;; - 8|'Kali Linux 2') - dist_version="jessie" - ;; - esac - fi - fi - fi -} - -semverParse() { - major="${1%%.*}" - minor="${1#$major.}" - minor="${minor%%.*}" - patch="${1#$major.$minor.}" - patch="${patch%%[-.]*}" -} - -do_install() { - echo "# Executing docker install script, commit: $SCRIPT_COMMIT_SHA" - - if command_exists docker; then - docker_version="$(docker -v | cut -d ' ' -f3 | cut -d ',' -f1)" - MAJOR_W=1 - MINOR_W=10 - - semverParse "$docker_version" - - shouldWarn=0 - if [ "$major" -lt "$MAJOR_W" ]; then - shouldWarn=1 - fi - - if [ "$major" -le "$MAJOR_W" ] && [ "$minor" -lt "$MINOR_W" ]; then - shouldWarn=1 - fi - - cat >&2 <<-'EOF' - Warning: the "docker" command appears to already exist on this system. - - If you already have Docker installed, this script can cause trouble, which is - why we're displaying this warning and provide the opportunity to cancel the - installation. - - If you installed the current Docker package using this script and are using it - EOF - - if [ $shouldWarn -eq 1 ]; then - cat >&2 <<-'EOF' - again to update Docker, we urge you to migrate your image store before upgrading - to v1.10+. - - You can find instructions for this here: - https://github.com/docker/docker/wiki/Engine-v1.10.0-content-addressability-migration - EOF - else - cat >&2 <<-'EOF' - again to update Docker, you can safely ignore this message. - EOF - fi - - cat >&2 <<-'EOF' - - You may press Ctrl+C now to abort this script. - EOF - ( set -x; sleep 20 ) - fi - - user="$(id -un 2>/dev/null || true)" - - sh_c='sh -c' - if [ "$user" != 'root' ]; then - if command_exists sudo; then - sh_c='sudo -E sh -c' - elif command_exists su; then - sh_c='su -c' - else - cat >&2 <<-'EOF' - Error: this installer needs the ability to run commands as root. - We are unable to find either "sudo" or "su" available to make this happen. - EOF - exit 1 - fi - fi - - if is_dry_run; then - sh_c="echo" - fi - - # perform some very rudimentary platform detection - lsb_dist=$( get_distribution ) - lsb_dist="$(echo "$lsb_dist" | tr '[:upper:]' '[:lower:]')" - - if is_wsl; then - echo - echo "WSL DETECTED: We recommend using Docker Desktop for Windows." - echo "Please get Docker Desktop from https://www.docker.com/products/docker-desktop" - echo - cat >&2 <<-'EOF' - - You may press Ctrl+C now to abort this script. - EOF - ( set -x; sleep 20 ) - fi - - case "$lsb_dist" in - - ubuntu) - if command_exists lsb_release; then - dist_version="$(lsb_release --codename | cut -f2)" - fi - if [ -z "$dist_version" ] && [ -r /etc/lsb-release ]; then - dist_version="$(. /etc/lsb-release && echo "$DISTRIB_CODENAME")" - fi - ;; - - debian|raspbian) - dist_version="$(sed 's/\/.*//' /etc/debian_version | sed 's/\..*//')" - case "$dist_version" in - 10) - dist_version="buster" - ;; - 9) - dist_version="stretch" - ;; - 8) - dist_version="jessie" - ;; - esac - ;; - - centos|rhel) - if [ -z "$dist_version" ] && [ -r /etc/os-release ]; then - dist_version="$(. /etc/os-release && echo "$VERSION_ID")" - fi - ;; - - *) - if command_exists lsb_release; then - dist_version="$(lsb_release --release | cut -f2)" - fi - if [ -z "$dist_version" ] && [ -r /etc/os-release ]; then - dist_version="$(. /etc/os-release && echo "$VERSION_ID")" - fi - ;; - - esac - - # Check if this is a forked Linux distro - check_forked - - # Run setup for each distro accordingly - case "$lsb_dist" in - ubuntu|debian|raspbian) - pre_reqs="apt-transport-https ca-certificates curl" - if [ "$lsb_dist" = "debian" ]; then - # libseccomp2 does not exist for debian jessie main repos for aarch64 - if [ "$(uname -m)" = "aarch64" ] && [ "$dist_version" = "jessie" ]; then - add_debian_backport_repo "$dist_version" - fi - fi - - if ! command -v gpg > /dev/null; then - pre_reqs="$pre_reqs gnupg" - fi - apt_repo="deb [arch=$(dpkg --print-architecture)] $DOWNLOAD_URL/linux/$lsb_dist $dist_version $CHANNEL" - ( - if ! is_dry_run; then - set -x - fi - $sh_c 'apt-get update -qq >/dev/null' - $sh_c "DEBIAN_FRONTEND=noninteractive apt-get install -y -qq $pre_reqs >/dev/null" - $sh_c "curl -fsSL \"$DOWNLOAD_URL/linux/$lsb_dist/gpg\" | apt-key add -qq - >/dev/null" - $sh_c "echo \"$apt_repo\" > /etc/apt/sources.list.d/docker.list" - $sh_c 'apt-get update -qq >/dev/null' - ) - pkg_version="" - if [ -n "$VERSION" ]; then - if is_dry_run; then - echo "# WARNING: VERSION pinning is not supported in DRY_RUN" - else - # Will work for incomplete versions IE (17.12), but may not actually grab the "latest" if in the test channel - pkg_pattern="$(echo "$VERSION" | sed "s/-ce-/~ce~.*/g" | sed "s/-/.*/g").*-0~$lsb_dist" - search_command="apt-cache madison 'docker-ce' | grep '$pkg_pattern' | head -1 | awk '{\$1=\$1};1' | cut -d' ' -f 3" - pkg_version="$($sh_c "$search_command")" - echo "INFO: Searching repository for VERSION '$VERSION'" - echo "INFO: $search_command" - if [ -z "$pkg_version" ]; then - echo - echo "ERROR: '$VERSION' not found amongst apt-cache madison results" - echo - exit 1 - fi - search_command="apt-cache madison 'docker-ce-cli' | grep '$pkg_pattern' | head -1 | awk '{\$1=\$1};1' | cut -d' ' -f 3" - # Don't insert an = for cli_pkg_version, we'll just include it later - cli_pkg_version="$($sh_c "$search_command")" - pkg_version="=$pkg_version" - fi - fi - ( - if ! is_dry_run; then - set -x - fi - if [ -n "$cli_pkg_version" ]; then - $sh_c "apt-get install -y -qq --no-install-recommends docker-ce-cli=$cli_pkg_version >/dev/null" - fi - $sh_c "apt-get install -y -qq --no-install-recommends docker-ce$pkg_version >/dev/null" - # shellcheck disable=SC2030 - if [ -n "$has_rootless_extras" ]; then - # Install docker-ce-rootless-extras without "--no-install-recommends", so as to install slirp4netns when available - $sh_c "DEBIAN_FRONTEND=noninteractive apt-get install -y -qq docker-ce-rootless-extras$pkg_version >/dev/null" - fi - ) - echo_docker_as_nonroot - exit 0 - ;; - centos|fedora|rhel) - yum_repo="$DOWNLOAD_URL/linux/$lsb_dist/$REPO_FILE" - if ! curl -Ifs "$yum_repo" > /dev/null; then - echo "Error: Unable to curl repository file $yum_repo, is it valid?" - exit 1 - fi - if [ "$lsb_dist" = "fedora" ]; then - pkg_manager="dnf" - config_manager="dnf config-manager" - enable_channel_flag="--set-enabled" - disable_channel_flag="--set-disabled" - pre_reqs="dnf-plugins-core" - pkg_suffix="fc$dist_version" - else - pkg_manager="yum" - config_manager="yum-config-manager" - enable_channel_flag="--enable" - disable_channel_flag="--disable" - pre_reqs="yum-utils" - pkg_suffix="el" - fi - ( - if ! is_dry_run; then - set -x - fi - $sh_c "$pkg_manager install -y -q $pre_reqs" - $sh_c "$config_manager --add-repo $yum_repo" - - if [ "$CHANNEL" != "stable" ]; then - $sh_c "$config_manager $disable_channel_flag docker-ce-*" - $sh_c "$config_manager $enable_channel_flag docker-ce-$CHANNEL" - fi - $sh_c "$pkg_manager makecache" - ) - pkg_version="" - if [ -n "$VERSION" ]; then - if is_dry_run; then - echo "# WARNING: VERSION pinning is not supported in DRY_RUN" - else - pkg_pattern="$(echo "$VERSION" | sed "s/-ce-/\\\\.ce.*/g" | sed "s/-/.*/g").*$pkg_suffix" - search_command="$pkg_manager list --showduplicates 'docker-ce' | grep '$pkg_pattern' | tail -1 | awk '{print \$2}'" - pkg_version="$($sh_c "$search_command")" - echo "INFO: Searching repository for VERSION '$VERSION'" - echo "INFO: $search_command" - if [ -z "$pkg_version" ]; then - echo - echo "ERROR: '$VERSION' not found amongst $pkg_manager list results" - echo - exit 1 - fi - search_command="$pkg_manager list --showduplicates 'docker-ce-cli' | grep '$pkg_pattern' | tail -1 | awk '{print \$2}'" - # It's okay for cli_pkg_version to be blank, since older versions don't support a cli package - cli_pkg_version="$($sh_c "$search_command" | cut -d':' -f 2)" - # Cut out the epoch and prefix with a '-' - pkg_version="-$(echo "$pkg_version" | cut -d':' -f 2)" - fi - fi - ( - if ! is_dry_run; then - set -x - fi - # install the correct cli version first - if [ -n "$cli_pkg_version" ]; then - $sh_c "$pkg_manager install -y -q docker-ce-cli-$cli_pkg_version" - fi - $sh_c "$pkg_manager install -y -q docker-ce$pkg_version" - # shellcheck disable=SC2031 - if [ -n "$has_rootless_extras" ]; then - $sh_c "$pkg_manager install -y -q docker-ce-rootless-extras$pkg_version" - fi - ) - echo_docker_as_nonroot - exit 0 - ;; - *) - if [ -z "$lsb_dist" ]; then - if is_darwin; then - echo - echo "ERROR: Unsupported operating system 'macOS'" - echo "Please get Docker Desktop from https://www.docker.com/products/docker-desktop" - echo - exit 1 - fi - fi - echo - echo "ERROR: Unsupported distribution '$lsb_dist'" - echo - exit 1 - ;; - esac - exit 1 -} - -# wrapped up in a function so that we have some protection against only getting -# half the file during "curl | sh" -do_install diff --git a/deprecated!/gunicorn.conf b/deprecated!/gunicorn.conf deleted file mode 100644 index 0b989a5fb..000000000 --- a/deprecated!/gunicorn.conf +++ /dev/null @@ -1,7 +0,0 @@ -# -*- mode: python -*- -# vi: set ft=python : - -import os - -bind = '127.0.0.1:%s' % os.environ['PORT'] -workers = 3 diff --git a/deprecated!/makemigrations b/deprecated!/makemigrations deleted file mode 100755 index 10176141d..000000000 --- a/deprecated!/makemigrations +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -rm dev.db -foreman run python manage.py syncdb -foreman run python manage.py migrate diff --git a/deprecated!/setup.cfg b/deprecated!/setup.cfg deleted file mode 100644 index 2eeeef9e1..000000000 --- a/deprecated!/setup.cfg +++ /dev/null @@ -1,7 +0,0 @@ -[isort] -known_first_party = cabot -multi_line_output = 0 -known_django = django,polymorphic,rest_framework -sections = FUTURE,STDLIB,THIRDPARTY,DJANGO,FIRSTPARTY,LOCALFOLDER -default_section = THIRDPARTY -skip_glob = **/migrations/* diff --git a/deprecated!/setup_dev.sh b/deprecated!/setup_dev.sh deleted file mode 100755 index edd90ef78..000000000 --- a/deprecated!/setup_dev.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -foreman run python manage.py syncdb -foreman run python manage.py migrate diff --git a/deprecated!/upstart/process.conf.erb b/deprecated!/upstart/process.conf.erb deleted file mode 100644 index c3df16525..000000000 --- a/deprecated!/upstart/process.conf.erb +++ /dev/null @@ -1,6 +0,0 @@ -start on starting <%= app %>-<%= name %> -stop on stopping <%= app %>-<%= name %> -respawn -respawn limit 50 5 - -exec su - <%= user %> -c 'cd <%= engine.root %>; export PORT=<%= port %>;<% engine.env.each_pair do |var,env| %> export <%= var.upcase %>='\''<%= env %>'\''; <% end %> export TMPDIR=$TMPDIR/<%= app %>/<%= name %>/<%= num %>; rm -rf $TMPDIR; mkdir -p $TMPDIR; source $VENV/bin/activate; <%= process.command %> >> <%= log %>/<%=name%>-<%=num%>.log 2>&1' diff --git a/deprecated!/docker-compose.yml b/docker-compose copy.yml similarity index 95% rename from deprecated!/docker-compose.yml rename to docker-compose copy.yml index 4742c6724..110beeee5 100644 --- a/deprecated!/docker-compose.yml +++ b/docker-compose copy.yml @@ -43,7 +43,7 @@ services: file: docker-compose-base.yml service: base env_file: - - conf/development.env + - .env command: python manage.py migrate command: python manage.py runserver 0.0.0.0:8000 ports: @@ -57,7 +57,7 @@ services: file: docker-compose-base.yml service: base env_file: - - conf/development.env + - .env command: celery -A cabot worker --beat --scheduler django --loglevel=info environment: - SKIP_INIT=1 diff --git a/docker-compose-base.yml b/docker-compose-base.yml index 1cc952e53..9940c5eea 100644 --- a/docker-compose-base.yml +++ b/docker-compose-base.yml @@ -2,9 +2,9 @@ version: '3' services: base: build: . - image: t_dk + image: cabot-image command: "false" volumes: - .:/code env_file: - - conf/development.env + - .env diff --git a/docker-compose.yml b/docker-compose.yml index 4742c6724..24fb84e61 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,70 +1,16 @@ version: '3' services: - db: - container_name: cabot_pg - image: postgres:alpine - restart: always - environment: - POSTGRES_USER: root - POSTGRES_PASSWORD: root - POSTGRES_DB: test_db - ports: - - "5432:5432" - volumes: - - datavolume:/var/lib/postgresql/data - - pgadmin: - container_name: cabot_pg_admin - image: dpage/pgadmin4 - restart: always - environment: - PGADMIN_DEFAULT_EMAIL: admin@admin.com - PGADMIN_DEFAULT_PASSWORD: root - ports: - - "5050:80" - - redis: - container_name: cabot_redis - image: redislabs/redismod - restart: always - ports: - - 6379:6379 - - redisinsight: - container_name: cabot_redis_admin - image: redislabs/redisinsight:latest - restart: always - ports: - - '8001:8001' - web: build: . extends: file: docker-compose-base.yml service: base env_file: - - conf/development.env + - .env command: python manage.py migrate command: python manage.py runserver 0.0.0.0:8000 ports: - "8000:8000" - links: - - redis - - db - - worker-beat: - extends: - file: docker-compose-base.yml - service: base - env_file: - - conf/development.env - command: celery -A cabot worker --beat --scheduler django --loglevel=info - environment: - - SKIP_INIT=1 - - WAIT_FOR_MIGRATIONS=1 - links: - - redis - - db volumes: diff --git a/example_local_config.yml b/example_local_config.yml deleted file mode 100644 index b1081c5df..000000000 --- a/example_local_config.yml +++ /dev/null @@ -1,13 +0,0 @@ ---- -# Example Local Vagrant config -# With this file, you can override the amount of RAM and CPUs allocated -# to the VM, as well as change the base box it uses. Just copy it to -# local_config.yml and edit with whatever values you want. -# -# Note that it doesn't take effect until you vagrant destroy && vagrant up - -# double your pleasure double your CPU and RAM -ram: 2048 -cpu: 2 -# hashicorp ubuntu doesn't support VMWare, so use box-cutter -box: box-cutter/ubuntu1404 diff --git a/gunicorn.conf b/gunicorn.conf deleted file mode 100644 index 0b989a5fb..000000000 --- a/gunicorn.conf +++ /dev/null @@ -1,7 +0,0 @@ -# -*- mode: python -*- -# vi: set ft=python : - -import os - -bind = '127.0.0.1:%s' % os.environ['PORT'] -workers = 3 diff --git a/makemigrations b/makemigrations deleted file mode 100755 index 10176141d..000000000 --- a/makemigrations +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -rm dev.db -foreman run python manage.py syncdb -foreman run python manage.py migrate diff --git a/manage.py b/manage.py index 92e6d37e1..ede6b8f10 100755 --- a/manage.py +++ b/manage.py @@ -1,16 +1,12 @@ #!/usr/bin/env python import os import sys -from cabot.config import config_charge if __name__ == "__main__": - #carga de enviroment - config_charge() - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cabot.settings") diff --git a/requirements-plugins.txt b/requirements-plugins.txt index e8765ad1e..4b398668f 100644 --- a/requirements-plugins.txt +++ b/requirements-plugins.txt @@ -1,4 +1 @@ -git+https://github.com/senzil/cabot-alert-email.git -git+https://github.com/senzil/cabot-check-http.git -git+https://github.com/senzil/cabot-alert-slack.git -git+https://github.com/senzil/cabot-check-network.git \ No newline at end of file +/home/tomas/Escritorio/code/cabot/Plugins-Cabot/core \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index a52497dc0..dad2ecd9a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,128 +1,49 @@ amqp==5.0.6 -anyjson==0.3.3 -appdirs==1.4.4 -argh==0.26.2 asgiref==3.4.1 -astroid==2.6.2 -Babel==2.9.1 -backcall==0.2.0 -bashate==2.0.0 billiard==3.6.4.0 -boto==2.49.0 -boto3==1.17.106 -botocore==1.20.106 cached-property==1.5.2 -cairocffi==1.0.0 celery==5.1.2 certifi==2021.5.30 -cffi==1.14.5 chardet==4.0.0 click==7.1.2 click-didyoumean==0.0.3 click-plugins==1.1.1 click-repl==0.2.0 -coffee-compressor-compiler==0.2.0 coreapi==2.3.3 coreschema==0.0.4 -cryptography==3.4.7 -decorator==5.0.9 -defusedxml==0.7.1 dj-database-url==0.5.0 Django==3.2.5 django-appconf==1.0.4 -django-auth-ldap==2.4.0 django-autocomplete-light==3.8.2 django-bootstrap-form==3.4 django-celery-beat==2.2.1 -django-common-helpers==0.9.2 django-compressor==2.4.1 -django-crontab==0.7.1 django-filter==2.4.0 django-jsonify==0.3.0 django-polymorphic==3.0.0 -django-tagging==0.4.3 -django-task==2.0.1 django-timezone-field==4.2.1 djangorestframework==3.12.4 -docutils==0.17.1 -dramatiq==1.11.0 -flake8==3.9.2 -gevent==21.1.2 -greenlet==1.1.0 -httplib2==0.19.1 -huey==2.3.2 icalendar==4.0.7 idna==2.10 -importlib-metadata==4.6.1 -ipython==7.16.1 -ipython-genutils==0.2.0 +importlib-metadata==4.6.3 itypes==1.2.0 -jedi==0.18.0 Jinja2==3.0.1 -jmespath==0.10.0 kombu==5.1.0 -lazy-object-proxy==1.6.0 -Markdown==3.3.4 MarkupSafe==2.0.1 -mccabe==0.6.1 -multi-key-dict==2.0.3 -oauthlib==3.1.1 -packaging==21.0 -parso==0.8.2 -pathtools==0.1.2 -pbr==5.6.0 -pexpect==4.8.0 -pickleshare==0.7.5 -pika==1.2.0 -prometheus-client==0.11.0 prompt-toolkit==3.0.19 -psycopg2==2.7.7 -mysqlclient psycopg2-binary==2.9.1 -ptyprocess==0.7.0 -pyasn1==0.4.8 -pyasn1-modules==0.2.8 -pycodestyle==2.7.0 -pycparser==2.20 -PyExecJS==1.5.1 -pyflakes==2.3.1 -Pygments==2.9.0 -PyJWT==2.1.0 -pylint==2.9.3 -pyparsing==2.4.7 -PySocks==1.7.1 python-crontab==2.5.1 -python-dateutil==2.8.1 -python-jenkins==1.7.0 -python-ldap==3.3.1 -python-openid==2.2.5 -python3-openid==3.2.0 +python-dateutil==2.8.2 pytz==2021.1 -PyYAML==5.4.1 rcssmin==1.0.6 redis==3.5.3 requests==2.25.1 -requests-oauthlib==1.3.0 rjsmin==1.1.0 -s3transfer==0.4.2 -scandir==1.10.0 six==1.16.0 -social-auth-app-django==4.0.0 -social-auth-core==4.1.0 sqlparse==0.4.1 -toml==0.10.2 -traitlets==4.3.3 -twilio==6.50.1 -typed-ast==1.4.3 typing-extensions==3.10.0.0 uritemplate==3.0.1 urllib3==1.26.6 vine==5.0.0 -watchdog==0.8.3 -watchdog-gevent==0.1.0 wcwidth==0.2.5 -whitenoise==5.2.0 -wrapt==1.12.1 -zipp==3.5.0 -zope.event==4.5.0 -zope.interface==5.4.0 +zipp==3.5.0 \ No newline at end of file diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 2eeeef9e1..000000000 --- a/setup.cfg +++ /dev/null @@ -1,7 +0,0 @@ -[isort] -known_first_party = cabot -multi_line_output = 0 -known_django = django,polymorphic,rest_framework -sections = FUTURE,STDLIB,THIRDPARTY,DJANGO,FIRSTPARTY,LOCALFOLDER -default_section = THIRDPARTY -skip_glob = **/migrations/* diff --git a/setup.py b/setup.py deleted file mode 100644 index 5df0466b6..000000000 --- a/setup.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env python -import os -from setuptools import setup, find_packages -from os import environ as env -import subprocess - -from pip.req import parse_requirements - -requirements = [str(req.req) for req in parse_requirements('requirements.txt', session=False)] -requirements_plugins = [str(req.req) for req in parse_requirements('requirements-plugins.txt', session=False)] - -try: - VERSION = subprocess.check_output(['git', 'describe', '--tags']).strip() -except subprocess.CalledProcessError: - VERSION = '0.dev' - -setup( - name='cabot', - version=VERSION, - description="Self-hosted, easily-deployable monitoring and alerts service" - " - like a lightweight PagerDuty", - long_description=open('README.md').read(), - author="Arachnys", - author_email='info@arachnys.com', - url='http://cabotapp.com', - license='MIT', - install_requires=requirements + requirements_plugins, - packages=find_packages(), - include_package_data=True, - entry_points={ - 'console_scripts': [ - 'cabot = cabot.entrypoint:main', - ], - }, - zip_safe=False -) diff --git a/setup_dev.sh b/setup_dev.sh deleted file mode 100755 index edd90ef78..000000000 --- a/setup_dev.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -foreman run python manage.py syncdb -foreman run python manage.py migrate diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 3d6f8f2b9..000000000 --- a/tox.ini +++ /dev/null @@ -1,75 +0,0 @@ -[tox] -envlist = config,flake8,bashate -skipsdist = True - -[testenv] -whitelist_externals = - bash - -[testenv:config] -commands = - /bin/bash -c 'set -euo pipefail && . ./conf/production.env.example' - /bin/bash -c 'set -euo pipefail && . ./conf/development.env.example' - -[testenv:bashate] -deps = bashate==2.0.0 -commands = - # Run bashate check for all bash scripts - # Ignores the following rules: - # E003: Indent not multiple of 4 (we use multiples of 2) - # E006: Line longer than 79 columns - bash -c "grep --recursive --binary-files=without-match \ - --files-with-match '^.!.*\(ba\)\?sh$' \ - --exclude-dir .tox \ - --exclude-dir .git \ - {toxinidir} | xargs bashate --error . --verbose --ignore=E003,E006" - -[testenv:flake8] -deps = - flake8 - flake8-debugger -commands = flake8 {posargs} - -[testenv:isort] -deps = isort==4.2.15 -commands = - bash -c "find {toxinidir} \ - -type d \ - \( \ - -path {toxinidir}/.git -o \ - -path {toxinidir}/.tox -o \ - -path {toxinidir}/.venv -o \ - -path {toxinidir}/plugins -o \ - -path {toxinidir}/node_modules \ - \) -prune -o \ - -name '*.py' \ - -print | xargs isort {posargs:--check-only} --verbose" - -[flake8] -exclude = .venv,venv,.tox,dist,doc,build,*.egg,docs,setup.py,*/migrations/ -ignore = E121,E123,E125,E126,E127,E128,E131,E222,E226,E231,E251,E261,E265,E302,E305,E402,E714,E722,F401,F403,F405,F841,W391,W605 -max-line-length = 160 -# E121 continuation line under-indented for hanging indent -# E123 closing bracket does not match indentation of opening bracket's line -# E125 continuation line with same indent as next logical line -# E126 continuation line over-indented for hanging indent -# E127 continuation line over-indented for visual indent -# E128 continuation line under-indented for visual indent -# E131 continuation line unaligned for hanging indent -# E222 multiple spaces after operator -# E226 missing whitespace around arithmetic operator -# E231 missing whitespace after -# E251 unexpected spaces around keyword / parameter equals -# E261 at least two spaces before inline comment -# E265 block comment should start with '# ' -# E302 expected 2 blank lines, found 1 -# E305 expected 2 blank lines after class or function definition, found 1 -# E402 module level import not at top of file -# E714 test for object identity should be 'is not' -# E722 do not use bare except -# F401 Imported but unused -# F403 'from module import *' used; unable to detect undefined names -# F405 foo may be undefined, or defined from star imports -# F841 local variable 'foo' is assigned to but never used -# W391 blank line at end of file -# W605 invalid escape sequence diff --git a/upstart/process.conf.erb b/upstart/process.conf.erb deleted file mode 100644 index c3df16525..000000000 --- a/upstart/process.conf.erb +++ /dev/null @@ -1,6 +0,0 @@ -start on starting <%= app %>-<%= name %> -stop on stopping <%= app %>-<%= name %> -respawn -respawn limit 50 5 - -exec su - <%= user %> -c 'cd <%= engine.root %>; export PORT=<%= port %>;<% engine.env.each_pair do |var,env| %> export <%= var.upcase %>='\''<%= env %>'\''; <% end %> export TMPDIR=$TMPDIR/<%= app %>/<%= name %>/<%= num %>; rm -rf $TMPDIR; mkdir -p $TMPDIR; source $VENV/bin/activate; <%= process.command %> >> <%= log %>/<%=name%>-<%=num%>.log 2>&1' From d054e7a991f1ff2353d8885a3e45ac9017972e3c Mon Sep 17 00:00:00 2001 From: Ladrusca Date: Fri, 6 Aug 2021 14:10:57 -0300 Subject: [PATCH 06/24] resuelto el dockerfile --- Dockerfile | 11 ++++++---- cabot/settings.py | 4 +--- docker-compose copy.yml | 2 +- docker-compose.yml | 41 +++++++++++++++++++++++++++++++++++-- docker-entrypoint.sh | 44 +--------------------------------------- requirements-plugins.txt | 5 ++++- requirements.txt | 3 +++ 7 files changed, 56 insertions(+), 54 deletions(-) diff --git a/Dockerfile b/Dockerfile index fa658cadd..d27ed3044 100644 --- a/Dockerfile +++ b/Dockerfile @@ -41,6 +41,8 @@ RUN pip install --no-cache-dir -r requirements.txt ######################################################## FROM python:3.6-alpine AS runner-image +RUN apk add --no-cache libpq + RUN adduser -S cabot COPY --from=builder-image /home/cabot/venv /home/cabot/venv @@ -48,8 +50,8 @@ USER cabot RUN mkdir /home/cabot/code WORKDIR /home/cabot/code -COPY cabot . -COPY manage.py ./cabot +COPY ./cabot ./cabot +COPY manage.py ./manage.py EXPOSE 8000 @@ -62,7 +64,8 @@ ENV PATH="/home/cabot/venv/bin:$PATH" # /dev/shm is mapped to shared memory and should be used for gunicorn heartbeat # this will improve performance and avoid random freezes -CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"] + +#CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"] -#ENTRYPOINT ["./docker-entrypoint.sh"] \ No newline at end of file +ENTRYPOINT ["docker-entrypoint.sh"] \ No newline at end of file diff --git a/cabot/settings.py b/cabot/settings.py index 9c1f0257f..fab49a246 100644 --- a/cabot/settings.py +++ b/cabot/settings.py @@ -32,7 +32,7 @@ 'NAME': os.environ.get('DATABASE_NAME', 'cabot'), 'USER': os.environ.get('DATABASE_USER', 'root'), 'PASSWORD': os.environ.get('DATABASE_PASSWORD', 'root'), - 'HOST': os.environ.get('DATABASE_HOST', '127.0.0.1'), + 'HOST': os.environ.get('DATABASE_HOST', '172.26.0.2'), 'PORT': os.environ.get('DATABASE_PORT', '5432'), } } @@ -339,5 +339,3 @@ EXPOSE_USER_API = force_bool(os.environ.get('EXPOSE_USER_API', False)) ENABLE_SUBSCRIPTION = force_bool(os.environ.get('ENABLE_SUBSCRIPTION', True)) ENABLE_DUTY_ROTA = force_bool(os.environ.get('ENABLE_DUTY_ROTA', True)) - - diff --git a/docker-compose copy.yml b/docker-compose copy.yml index 110beeee5..7e03f776a 100644 --- a/docker-compose copy.yml +++ b/docker-compose copy.yml @@ -21,7 +21,7 @@ services: PGADMIN_DEFAULT_EMAIL: admin@admin.com PGADMIN_DEFAULT_PASSWORD: root ports: - - "5050:80" + - "5050:5050" redis: container_name: cabot_redis diff --git a/docker-compose.yml b/docker-compose.yml index 24fb84e61..b54f337ff 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,25 @@ version: '3' services: + db: + container_name: cabot_pg + image: postgres:alpine + restart: always + environment: + POSTGRES_USER: root + POSTGRES_PASSWORD: root + POSTGRES_DB: test_db + ports: + - "5432:5432" + volumes: + - datavolume:/var/lib/postgresql/data + + redis: + container_name: cabot_redis + image: redislabs/redismod + restart: always + ports: + - 6379:6379 + web: build: . extends: @@ -7,10 +27,27 @@ services: service: base env_file: - .env - command: python manage.py migrate - command: python manage.py runserver 0.0.0.0:8000 + + command: "python manage.py runserver 0.0.0.0:8000" ports: - "8000:8000" + links: + - redis + - db + + worker-beat: + extends: + file: docker-compose-base.yml + service: base + env_file: + - .env + command: celery -A cabot worker --beat --scheduler django --loglevel=info + environment: + - SKIP_INIT=1 + - WAIT_FOR_MIGRATIONS=1 + links: + - redis + - db volumes: diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 274c80c2c..4731c59cc 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -1,45 +1,3 @@ #!/bin/bash -set -e -function wait_for_broker { - set +e - for try in {1..60} ; do - python -c "from kombu import Connection; x=Connection('$CELERY_BROKER_URL', timeout=1); x.connect()" && break - echo "Waiting for celery broker to respond..." - sleep 1 - done -} - -function wait_for_database { - set +e - for try in {1..60} ; do - python -c "from django.db import connection; connection.connect()" && break - echo "Waiting for database to respond..." - sleep 1 - done -} - -function wait_for_migrations { - set +e - for try in {1..60} ; do - # Kind of ugly but not sure if there's another way to determine if migrations haven't run. - # showmigrations -p returns a checkbox list of migrations, empty checkboxes mean they haven't been run - python manage.py showmigrations -p | grep "\[ \]" &> /dev/null || break - echo "Waiting for database migrations to be run..." - sleep 1 - done -} - - -wait_for_broker -wait_for_database - -if [ -z "$SKIP_INIT" ]; then - /code/bin/build-app -fi - -if [ -n "$WAIT_FOR_MIGRATIONS" ]; then - wait_for_migrations -fi - -exec "$@" +python3 manage.py migrate \ No newline at end of file diff --git a/requirements-plugins.txt b/requirements-plugins.txt index 4b398668f..e8765ad1e 100644 --- a/requirements-plugins.txt +++ b/requirements-plugins.txt @@ -1 +1,4 @@ -/home/tomas/Escritorio/code/cabot/Plugins-Cabot/core \ No newline at end of file +git+https://github.com/senzil/cabot-alert-email.git +git+https://github.com/senzil/cabot-check-http.git +git+https://github.com/senzil/cabot-alert-slack.git +git+https://github.com/senzil/cabot-check-network.git \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index dad2ecd9a..80c364b03 100644 --- a/requirements.txt +++ b/requirements.txt @@ -31,6 +31,9 @@ Jinja2==3.0.1 kombu==5.1.0 MarkupSafe==2.0.1 prompt-toolkit==3.0.19 +mysqlclient +postgres +psycopg2 psycopg2-binary==2.9.1 python-crontab==2.5.1 python-dateutil==2.8.2 From 73531e112fa60c74e0d44ff56e38705d03232db7 Mon Sep 17 00:00:00 2001 From: Ladrusca Date: Mon, 9 Aug 2021 01:28:08 -0300 Subject: [PATCH 07/24] resueltas las fallas en migraciones, faltante de archivos css, terminada la imagen docker y compose --- .gitignore | 10 +- Dockerfile | 13 +- Dockerfile-j | 71 ---- cabot/cabotapp/migrations/0001_initial.py | 318 +++++++----------- .../migrations/0002_auto_20170131_1537.py | 23 -- .../migrations/0003_auto_20170201_1045.py | 29 -- .../migrations/0004_auto_20170802_1327.py | 19 -- .../migrations/0005_auto_20170818_1202.py | 107 ------ .../migrations/0006_auto_20170821_1000.py | 22 -- ..._statuscheckresult_consecutive_failures.py | 20 -- .../migrations/0008_auto_20210707_1645.py | 256 -------------- .../migrations/0009_auto_20210719_2116.py | 29 -- .../migrations/0010_auto_20210720_1338.py | 33 -- cabot/settings.py | 18 +- cabot/static/arachnys/css/base.css | 43 +++ docker-compose copy.yml | 72 ---- docker-compose-base.yml | 2 +- docker-compose-test.yml | 13 - docker-compose.yml | 25 +- docker-entrypoint.sh | 44 ++- docker.env_example | 66 ++++ requiements.txt | 111 ------ requirements-dev.txt | 6 - requirements-plugins.txt | 2 +- requirements.txt | 12 +- 25 files changed, 318 insertions(+), 1046 deletions(-) delete mode 100644 Dockerfile-j delete mode 100644 cabot/cabotapp/migrations/0002_auto_20170131_1537.py delete mode 100644 cabot/cabotapp/migrations/0003_auto_20170201_1045.py delete mode 100644 cabot/cabotapp/migrations/0004_auto_20170802_1327.py delete mode 100644 cabot/cabotapp/migrations/0005_auto_20170818_1202.py delete mode 100644 cabot/cabotapp/migrations/0006_auto_20170821_1000.py delete mode 100644 cabot/cabotapp/migrations/0007_statuscheckresult_consecutive_failures.py delete mode 100644 cabot/cabotapp/migrations/0008_auto_20210707_1645.py delete mode 100644 cabot/cabotapp/migrations/0009_auto_20210719_2116.py delete mode 100644 cabot/cabotapp/migrations/0010_auto_20210720_1338.py create mode 100644 cabot/static/arachnys/css/base.css delete mode 100644 docker-compose copy.yml delete mode 100644 docker-compose-test.yml mode change 100755 => 100644 docker-entrypoint.sh create mode 100644 docker.env_example delete mode 100644 requiements.txt delete mode 100644 requirements-dev.txt diff --git a/.gitignore b/.gitignore index acb04e66e..34d46dd31 100644 --- a/.gitignore +++ b/.gitignore @@ -2,12 +2,10 @@ dev.db venv/* backups/* -static/ cabot/.collectstatic/ node_modules/* .python-eggs/* cabot.egg-info -cabot/static/ .env .DS_Store celerybeat-schedule @@ -20,6 +18,7 @@ dist/ local_config.yml build/ .dockerignore +docker.env .idea Pipfile.lock .tox/ @@ -127,6 +126,7 @@ __pypackages__/ # Celery stuff celerybeat-schedule celerybeat.pid +.vscode # SageMath parsed files *.sage.py @@ -166,8 +166,4 @@ cython_debug/ # End of https://www.toptal.com/developers/gitignore/api/python -Dockerfile -requirements-plugins.txt -requirements-dev.txt -setup.py -Dockerfile copy \ No newline at end of file + diff --git a/Dockerfile b/Dockerfile index d27ed3044..fcf94f261 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,6 +6,7 @@ RUN apk update && apk add --no-cache \ py-pip \ postgresql-dev \ mariadb-dev \ + mysql-client \ gcc \ curl \ curl-dev \ @@ -19,7 +20,8 @@ RUN apk update && apk add --no-cache \ python3-dev \ musl-dev \ libevent-dev \ - bash + bash \ + git # create and activate virtual environment # using final folder name to avoid path issues with packages @@ -38,10 +40,14 @@ WORKDIR /code COPY requirements.txt ./ RUN pip install --no-cache-dir -r requirements.txt +COPY requirements-plugins.txt ./ +RUN pip install --no-cache-dir -force-reinstall -r requirements-plugins.txt + ######################################################## FROM python:3.6-alpine AS runner-image -RUN apk add --no-cache libpq +RUN apk add --no-cache libpq \ + mariadb-connector-c-dev RUN adduser -S cabot COPY --from=builder-image /home/cabot/venv /home/cabot/venv @@ -52,6 +58,7 @@ WORKDIR /home/cabot/code COPY ./cabot ./cabot COPY manage.py ./manage.py +COPY docker-entrypoint.sh ./docker-entrypoint.sh EXPOSE 8000 @@ -68,4 +75,4 @@ ENV PATH="/home/cabot/venv/bin:$PATH" #CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"] -ENTRYPOINT ["docker-entrypoint.sh"] \ No newline at end of file +ENTRYPOINT ["sh","docker-entrypoint.sh"] diff --git a/Dockerfile-j b/Dockerfile-j deleted file mode 100644 index 5f112fad2..000000000 --- a/Dockerfile-j +++ /dev/null @@ -1,71 +0,0 @@ -FROM python:3.6.5-slim-jessie AS builder-image - -RUN apt-get update -RUN DEBIAN_FRONTEND=noninteractive apt-get install -y \ - libmysqlclient-dev \ - build-essential \ - python3-dev \ - python2.7-dev \ - libldap2-dev \ - libsasl2-dev \ - slapd \ - ldap-utils \ - python-tox \ - lcov \ - valgrind\ - curl\ - python-dev \ - gcc \ - musl-dev \ - libffi-dev \ - ca-certificates \ - git\ - bash - - -# create and activate virtual environment -# using final folder name to avoid path issues with packages -RUN python3 -m venv /home/cabot/venv -ENV PATH="/home/cabot/venv/bin:$PATH" - - -ENV PYTHONUNBUFFERED 1 - -RUN pip install --upgrade pip - -RUN mkdir /code - -WORKDIR /code - -COPY requirements.txt ./ -RUN pip install --no-cache-dir -r requirements.txt - -######################################################## -FROM python:3.6.5-slim-jessie AS runner-image - -RUN apt-get update && apt-get install --no-install-recommends -y python3-venv && \ -apt-get clean && rm -rf /var/lib/apt/lists/* - -RUN useradd --create-home cabot -COPY --from=builder-image /home/cabot/venv /home/cabot/venv - -USER cabot -RUN mkdir /home/cabot/code -WORKDIR /home/cabot/code -COPY . . - -EXPOSE 8000 - -# make sure all messages always reach console -ENV PYTHONUNBUFFERED=1 - -# activate virtual environment -ENV VIRTUAL_ENV=/home/cabot/venv -ENV PATH="/home/cabot/venv/bin:$PATH" - -# /dev/shm is mapped to shared memory and should be used for gunicorn heartbeat -# this will improve performance and avoid random freezes -CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"] - - -#ENTRYPOINT ["./docker-entrypoint.sh"] \ No newline at end of file diff --git a/cabot/cabotapp/migrations/0001_initial.py b/cabot/cabotapp/migrations/0001_initial.py index c584e81eb..0c80ca3fe 100644 --- a/cabot/cabotapp/migrations/0001_initial.py +++ b/cabot/cabotapp/migrations/0001_initial.py @@ -1,293 +1,227 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals +# Generated by Django 3.2.5 on 2021-08-07 15:44 -from django.db import models, migrations from django.conf import settings +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion class Migration(migrations.Migration): + initial = True + dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('contenttypes', '0001_initial'), + ('contenttypes', '0002_remove_content_type_name'), ] operations = [ - migrations.CreateModel( - name='AlertAcknowledgement', - fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('time', models.DateTimeField()), - ('cancelled_time', models.DateTimeField(null=True, blank=True)), - ('cancelled_user', models.ForeignKey(related_name='cancelleduser_set', blank=True, to=settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE)), - ], - options={ - }, - bases=(models.Model,), - ), migrations.CreateModel( name='AlertPlugin', fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('title', models.CharField(unique=True, max_length=30, editable=False)), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(editable=False, max_length=30, unique=True)), ('enabled', models.BooleanField(default=True)), - ('polymorphic_ctype', models.ForeignKey(related_name='polymorphic_cabotapp.alertplugin_set', editable=False, to='contenttypes.ContentType', null=True, on_delete=models.CASCADE)), + ('polymorphic_ctype', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_cabotapp.alertplugin_set+', to='contenttypes.contenttype')), ], options={ 'abstract': False, + 'base_manager_name': 'objects', }, - bases=(models.Model,), - ), - migrations.CreateModel( - name='AlertPluginUserData', - fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('title', models.CharField(max_length=30, editable=False)), - ('polymorphic_ctype', models.ForeignKey(related_name='polymorphic_cabotapp.alertpluginuserdata_set', editable=False, to='contenttypes.ContentType', null=True, on_delete=models.CASCADE)), - ], - options={ - }, - bases=(models.Model,), ), migrations.CreateModel( name='Instance', fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.TextField()), - ('alerts_enabled', models.BooleanField(default=True, help_text=b'Alert when this service is not healthy.')), - ('last_alert_sent', models.DateTimeField(null=True, blank=True)), + ('alerts_enabled', models.BooleanField(default=True, help_text='Alert when this service is not healthy.')), + ('last_alert_sent', models.DateTimeField(blank=True, null=True)), ('email_alert', models.BooleanField(default=False)), ('hipchat_alert', models.BooleanField(default=True)), ('sms_alert', models.BooleanField(default=False)), - ('telephone_alert', models.BooleanField(default=False, help_text=b'Must be enabled, and check importance set to Critical, to receive telephone alerts.')), - ('overall_status', models.TextField(default=b'PASSING')), - ('old_overall_status', models.TextField(default=b'PASSING')), - ('hackpad_id', models.TextField(help_text=b'Gist, Hackpad or Refheap js embed with recovery instructions e.g. https://you.hackpad.com/some_document.js', null=True, verbose_name=b'Embedded recovery instructions', blank=True)), - ('runbook_link', models.TextField(help_text=b'Link to the service runbook on your wiki.', blank=True)), - ('address', models.TextField(help_text=b'Address (IP/Hostname) of service.', blank=True)), - ('alerts', models.ManyToManyField(help_text=b'Alerts channels through which you wish to be notified', to='cabotapp.AlertPlugin', blank=True)), + ('telephone_alert', models.BooleanField(default=False, help_text='Must be enabled, and check importance set to Critical, to receive telephone alerts.')), + ('overall_status', models.TextField(default='PASSING')), + ('old_overall_status', models.TextField(default='PASSING')), + ('hackpad_id', models.TextField(blank=True, help_text='Gist, Hackpad or Refheap js embed with recovery instructions e.g. https://you.hackpad.com/some_document.js', null=True, verbose_name='Embedded recovery instructions')), + ('runbook_link', models.TextField(blank=True, help_text='Link to the service runbook on your wiki.')), + ('address', models.TextField(blank=True, help_text='Address (IP/Hostname) of service.')), + ('alerts', models.ManyToManyField(blank=True, help_text='Alerts channels through which you wish to be notified', to='cabotapp.AlertPlugin')), ], options={ 'ordering': ['name'], }, - bases=(models.Model,), - ), - migrations.CreateModel( - name='InstanceStatusSnapshot', - fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('time', models.DateTimeField(db_index=True)), - ('num_checks_active', models.IntegerField(default=0)), - ('num_checks_passing', models.IntegerField(default=0)), - ('num_checks_failing', models.IntegerField(default=0)), - ('overall_status', models.TextField(default=b'PASSING')), - ('did_send_alert', models.IntegerField(default=False)), - ('instance', models.ForeignKey(related_name='snapshots', to='cabotapp.Instance', on_delete=models.CASCADE)), - ], - options={ - 'abstract': False, - }, - bases=(models.Model,), ), migrations.CreateModel( name='Service', fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.TextField()), - ('alerts_enabled', models.BooleanField(default=True, help_text=b'Alert when this service is not healthy.')), - ('last_alert_sent', models.DateTimeField(null=True, blank=True)), + ('alerts_enabled', models.BooleanField(default=True, help_text='Alert when this service is not healthy.')), + ('last_alert_sent', models.DateTimeField(blank=True, null=True)), ('email_alert', models.BooleanField(default=False)), ('hipchat_alert', models.BooleanField(default=True)), ('sms_alert', models.BooleanField(default=False)), - ('telephone_alert', models.BooleanField(default=False, help_text=b'Must be enabled, and check importance set to Critical, to receive telephone alerts.')), - ('overall_status', models.TextField(default=b'PASSING')), - ('old_overall_status', models.TextField(default=b'PASSING')), - ('hackpad_id', models.TextField(help_text=b'Gist, Hackpad or Refheap js embed with recovery instructions e.g. https://you.hackpad.com/some_document.js', null=True, verbose_name=b'Embedded recovery instructions', blank=True)), - ('runbook_link', models.TextField(help_text=b'Link to the service runbook on your wiki.', blank=True)), - ('url', models.TextField(help_text=b'URL of service.', blank=True)), - ('alerts', models.ManyToManyField(help_text=b'Alerts channels through which you wish to be notified', to='cabotapp.AlertPlugin', blank=True)), - ('instances', models.ManyToManyField(help_text=b'Instances this service is running on.', to='cabotapp.Instance', blank=True)), + ('telephone_alert', models.BooleanField(default=False, help_text='Must be enabled, and check importance set to Critical, to receive telephone alerts.')), + ('overall_status', models.TextField(default='PASSING')), + ('old_overall_status', models.TextField(default='PASSING')), + ('hackpad_id', models.TextField(blank=True, help_text='Gist, Hackpad or Refheap js embed with recovery instructions e.g. https://you.hackpad.com/some_document.js', null=True, verbose_name='Embedded recovery instructions')), + ('runbook_link', models.TextField(blank=True, help_text='Link to the service runbook on your wiki.')), + ('url', models.TextField(blank=True, help_text='URL of service.')), + ('is_public', models.BooleanField(default=False, help_text='The service will be shown in the public home', verbose_name='Is Public')), + ('alerts', models.ManyToManyField(blank=True, help_text='Alerts channels through which you wish to be notified', to='cabotapp.AlertPlugin')), + ('instances', models.ManyToManyField(blank=True, help_text='Instances this service is running on.', to='cabotapp.Instance')), ], options={ 'ordering': ['name'], }, - bases=(models.Model,), ), migrations.CreateModel( - name='ServiceStatusSnapshot', + name='StatusCheck', fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('time', models.DateTimeField(db_index=True)), - ('num_checks_active', models.IntegerField(default=0)), - ('num_checks_passing', models.IntegerField(default=0)), - ('num_checks_failing', models.IntegerField(default=0)), - ('overall_status', models.TextField(default=b'PASSING')), - ('did_send_alert', models.IntegerField(default=False)), - ('service', models.ForeignKey(related_name='snapshots', to='cabotapp.Service', on_delete=models.CASCADE)), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.TextField()), + ('active', models.BooleanField(default=True, help_text='If not active, check will not be used to calculate service status and will not trigger alerts.')), + ('importance', models.CharField(choices=[('WARNING', 'Warning'), ('ERROR', 'Error'), ('CRITICAL', 'Critical')], default='ERROR', help_text='Severity level of a failure. Critical alerts are for failures you want to wake you up at 2am, Errors are things you can sleep through but need to fix in the morning, and warnings for less important things.', max_length=30)), + ('frequency', models.IntegerField(default=5, help_text='Minutes between each check.')), + ('debounce', models.IntegerField(default=0, help_text='Number of successive failures permitted before check will be marked as failed. Default is 0, i.e. fail on first failure.', null=True)), + ('calculated_status', models.CharField(blank=True, choices=[('passing', 'passing'), ('intermittent', 'intermittent'), ('failing', 'failing')], default='passing', max_length=50)), + ('last_run', models.DateTimeField(null=True)), + ('cached_health', models.TextField(editable=False, null=True)), + ('metric', models.TextField(help_text='fully.qualified.name of the Graphite metric you want to watch. This can be any valid Graphite expression, including wildcards, multiple hosts, etc.', null=True)), + ('check_type', models.CharField(choices=[('>', 'Greater than'), ('>=', 'Greater than or equal'), ('<', 'Less than'), ('<=', 'Less than or equal'), ('==', 'Equal to')], max_length=100, null=True)), + ('value', models.TextField(help_text='If this expression evaluates to true, the check will fail (possibly triggering an alert).', null=True)), + ('expected_num_hosts', models.IntegerField(default=0, help_text='The minimum number of data series (hosts) you expect to see.', null=True)), + ('allowed_num_failures', models.IntegerField(default=0, help_text='The maximum number of data series (metrics) you expect to fail. For example, you might be OK with 2 out of 3 webservers having OK load (1 failing), but not 1 out of 3 (2 failing).', null=True)), + ('endpoint', models.TextField(help_text='HTTP(S) endpoint to poll.', null=True, validators=[django.core.validators.URLValidator()])), + ('username', models.TextField(blank=True, help_text='Basic auth username.', null=True)), + ('password', models.TextField(blank=True, help_text='Basic auth password.', null=True)), + ('text_match', models.TextField(blank=True, help_text='Regex to match against source of page.', null=True)), + ('status_code', models.TextField(default=200, help_text='Status code expected from endpoint.', null=True)), + ('timeout', models.IntegerField(default=30, help_text='Time out after this many seconds.', null=True)), + ('verify_ssl_certificate', models.BooleanField(default=True, help_text='Set to false to allow not try to verify ssl certificates (default True)')), + ('max_queued_build_time', models.IntegerField(blank=True, help_text='Alert if build queued for more than this many minutes.', null=True)), + ('created_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ('polymorphic_ctype', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_cabotapp.statuscheck_set+', to='contenttypes.contenttype')), ], options={ + 'ordering': ['name'], 'abstract': False, + 'base_manager_name': 'objects', }, - bases=(models.Model,), + ), + migrations.CreateModel( + name='UserProfile', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('mobile_number', models.CharField(blank=True, default='', max_length=20)), + ('hipchat_alias', models.CharField(blank=True, default='', max_length=50)), + ('fallback_alert_user', models.BooleanField(default=False)), + ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='profile', to=settings.AUTH_USER_MODEL)), + ], ), migrations.CreateModel( name='Shift', fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('start', models.DateTimeField()), ('end', models.DateTimeField()), ('uid', models.TextField()), ('last_modified', models.DateTimeField()), ('deleted', models.BooleanField(default=False)), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), - ], - options={ - }, - bases=(models.Model,), - ), - migrations.CreateModel( - name='StatusCheck', - fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('name', models.TextField()), - ('active', models.BooleanField(default=True, help_text=b'If not active, check will not be used to calculate service status and will not trigger alerts.')), - ('importance', models.CharField(default=b'ERROR', help_text=b'Severity level of a failure. Critical alerts are for failures you want to wake you up at 2am, Errors are things you can sleep through but need to fix in the morning, and warnings for less important things.', max_length=30, choices=[(b'WARNING', b'Warning'), (b'ERROR', b'Error'), (b'CRITICAL', b'Critical')])), - ('frequency', models.IntegerField(default=5, help_text=b'Minutes between each check.')), - ('debounce', models.IntegerField(default=0, help_text=b'Number of successive failures permitted before check will be marked as failed. Default is 0, i.e. fail on first failure.', null=True)), - ('calculated_status', models.CharField(default=b'passing', max_length=50, blank=True, choices=[(b'passing', b'passing'), (b'intermittent', b'intermittent'), (b'failing', b'failing')])), - ('last_run', models.DateTimeField(null=True)), - ('cached_health', models.TextField(null=True, editable=False)), - ('metric', models.TextField(help_text=b'fully.qualified.name of the Graphite metric you want to watch. This can be any valid Graphite expression, including wildcards, multiple hosts, etc.', null=True)), - ('check_type', models.CharField(max_length=100, null=True, choices=[(b'>', b'Greater than'), (b'>=', b'Greater than or equal'), (b'<', b'Less than'), (b'<=', b'Less than or equal'), (b'==', b'Equal to')])), - ('value', models.TextField(help_text=b'If this expression evaluates to true, the check will fail (possibly triggering an alert).', null=True)), - ('expected_num_hosts', models.IntegerField(default=0, help_text=b'The minimum number of data series (hosts) you expect to see.', null=True)), - ('allowed_num_failures', models.IntegerField(default=0, help_text=b'The maximum number of data series (metrics) you expect to fail. For example, you might be OK with 2 out of 3 webservers having OK load (1 failing), but not 1 out of 3 (2 failing).', null=True)), - ('endpoint', models.TextField(help_text=b'HTTP(S) endpoint to poll.', null=True)), - ('username', models.TextField(help_text=b'Basic auth username.', null=True, blank=True)), - ('password', models.TextField(help_text=b'Basic auth password.', null=True, blank=True)), - ('text_match', models.TextField(help_text=b'Regex to match against source of page.', null=True, blank=True)), - ('status_code', models.TextField(default=200, help_text=b'Status code expected from endpoint.', null=True)), - ('timeout', models.IntegerField(default=30, help_text=b'Time out after this many seconds.', null=True)), - ('verify_ssl_certificate', models.BooleanField(default=True, help_text=b'Set to false to allow not try to verify ssl certificates (default True)')), - ('max_queued_build_time', models.IntegerField(help_text=b'Alert if build queued for more than this many minutes.', null=True, blank=True)), - ('created_by', models.ForeignKey(to=settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE)), - ('polymorphic_ctype', models.ForeignKey(related_name='polymorphic_cabotapp.statuscheck_set', editable=False, to='contenttypes.ContentType', null=True, on_delete=models.CASCADE)), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ], - options={ - 'ordering': ['name'], - 'abstract': False, - }, - bases=(models.Model,), ), migrations.CreateModel( - name='StatusCheckResult', + name='ServiceStatusSnapshot', fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('time', models.DateTimeField(db_index=True)), - ('time_complete', models.DateTimeField(null=True, db_index=True)), - ('raw_data', models.TextField(null=True)), - ('succeeded', models.BooleanField(default=False)), - ('error', models.TextField(null=True)), - ('job_number', models.PositiveIntegerField(null=True)), - ('check', models.ForeignKey(to='cabotapp.StatusCheck', on_delete=models.CASCADE)), - ], - options={ - 'ordering': ['-time_complete'], - }, - bases=(models.Model,), - ), - migrations.CreateModel( - name='UserProfile', - fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('mobile_number', models.CharField(default=b'', max_length=20, blank=True)), - ('hipchat_alias', models.CharField(default=b'', max_length=50, blank=True)), - ('fallback_alert_user', models.BooleanField(default=False)), - ('user', models.OneToOneField(related_name='profile', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), + ('num_checks_active', models.IntegerField(default=0)), + ('num_checks_passing', models.IntegerField(default=0)), + ('num_checks_failing', models.IntegerField(default=0)), + ('overall_status', models.TextField(default='PASSING')), + ('did_send_alert', models.IntegerField(default=False)), + ('service', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='snapshots', to='cabotapp.service')), ], options={ + 'abstract': False, }, - bases=(models.Model,), - ), - migrations.AlterIndexTogether( - name='statuscheckresult', - index_together=set([('check', 'time_complete'), ('check', 'id')]), ), migrations.AddField( model_name='service', name='status_checks', - field=models.ManyToManyField(help_text=b'Checks used to calculate service status.', to='cabotapp.StatusCheck', blank=True), - preserve_default=True, + field=models.ManyToManyField(blank=True, help_text='Checks used to calculate service status.', to='cabotapp.StatusCheck'), ), migrations.AddField( model_name='service', name='users_to_notify', - field=models.ManyToManyField(help_text=b'Users who should receive alerts.', to=settings.AUTH_USER_MODEL, blank=True), - preserve_default=True, + field=models.ManyToManyField(blank=True, help_text='Users who should receive alerts.', to=settings.AUTH_USER_MODEL), + ), + migrations.CreateModel( + name='InstanceStatusSnapshot', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('time', models.DateTimeField(db_index=True)), + ('num_checks_active', models.IntegerField(default=0)), + ('num_checks_passing', models.IntegerField(default=0)), + ('num_checks_failing', models.IntegerField(default=0)), + ('overall_status', models.TextField(default='PASSING')), + ('did_send_alert', models.IntegerField(default=False)), + ('instance', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='snapshots', to='cabotapp.instance')), + ], + options={ + 'abstract': False, + }, ), migrations.AddField( model_name='instance', name='status_checks', - field=models.ManyToManyField(help_text=b'Checks used to calculate service status.', to='cabotapp.StatusCheck', blank=True), - preserve_default=True, + field=models.ManyToManyField(blank=True, help_text='Checks used to calculate service status.', to='cabotapp.StatusCheck'), ), migrations.AddField( model_name='instance', name='users_to_notify', - field=models.ManyToManyField(help_text=b'Users who should receive alerts.', to=settings.AUTH_USER_MODEL, blank=True), - preserve_default=True, - ), - migrations.AddField( - model_name='alertpluginuserdata', - name='user', - field=models.ForeignKey(editable=False, to='cabotapp.UserProfile', on_delete=models.CASCADE), - preserve_default=True, - ), - migrations.AlterUniqueTogether( - name='alertpluginuserdata', - unique_together=set([('title', 'user')]), - ), - migrations.AddField( - model_name='alertacknowledgement', - name='service', - field=models.ForeignKey(to='cabotapp.Service', on_delete=models.CASCADE), - preserve_default=True, - ), - migrations.AddField( - model_name='alertacknowledgement', - name='user', - field=models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE), - preserve_default=True, + field=models.ManyToManyField(blank=True, help_text='Users who should receive alerts.', to=settings.AUTH_USER_MODEL), ), migrations.CreateModel( - name='GraphiteStatusCheck', + name='AlertAcknowledgement', fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('time', models.DateTimeField()), + ('cancelled_time', models.DateTimeField(blank=True, null=True)), + ('cancelled_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='cancelleduser_set', to=settings.AUTH_USER_MODEL)), + ('service', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cabotapp.service')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ], - options={ - 'abstract': False, - 'proxy': True, - }, - bases=('cabotapp.statuscheck',), ), - migrations.CreateModel( - name='ICMPStatusCheck', + name='StatusCheckResult', fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('time', models.DateTimeField(db_index=True)), + ('time_complete', models.DateTimeField(db_index=True, null=True)), + ('raw_data', models.TextField(null=True)), + ('succeeded', models.BooleanField(default=False)), + ('error', models.TextField(null=True)), + ('job_number', models.PositiveIntegerField(null=True)), + ('consecutive_failures', models.PositiveIntegerField(null=True)), + ('status_check', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cabotapp.statuscheck')), ], options={ - 'abstract': False, - 'proxy': True, + 'ordering': ['-time_complete'], + 'index_together': {('status_check', 'id'), ('status_check', 'time_complete')}, }, - bases=('cabotapp.statuscheck',), ), migrations.CreateModel( - name='JenkinsStatusCheck', + name='AlertPluginUserData', fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(editable=False, max_length=30)), + ('polymorphic_ctype', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_cabotapp.alertpluginuserdata_set+', to='contenttypes.contenttype')), + ('user', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, to='cabotapp.userprofile')), ], options={ - 'abstract': False, - 'proxy': True, + 'unique_together': {('title', 'user')}, }, - bases=('cabotapp.statuscheck',), ), ] diff --git a/cabot/cabotapp/migrations/0002_auto_20170131_1537.py b/cabot/cabotapp/migrations/0002_auto_20170131_1537.py deleted file mode 100644 index d3f0b7859..000000000 --- a/cabot/cabotapp/migrations/0002_auto_20170131_1537.py +++ /dev/null @@ -1,23 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('cabotapp', '0001_initial'), - ] - - operations = [ - migrations.RenameField( - model_name='statuscheckresult', - old_name='check', - new_name='status_check', - ), - migrations.AlterIndexTogether( - name='statuscheckresult', - index_together=set([('status_check', 'time_complete'), ('status_check', 'id')]), - ), - ] diff --git a/cabot/cabotapp/migrations/0003_auto_20170201_1045.py b/cabot/cabotapp/migrations/0003_auto_20170201_1045.py deleted file mode 100644 index da979a391..000000000 --- a/cabot/cabotapp/migrations/0003_auto_20170201_1045.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('cabotapp', '0002_auto_20170131_1537'), - ] - - operations = [ - migrations.AlterField( - model_name='alertplugin', - name='polymorphic_ctype', - field=models.ForeignKey(related_name='polymorphic_cabotapp.alertplugin_set+', editable=False, to='contenttypes.ContentType', null=True, on_delete=models.CASCADE), - ), - migrations.AlterField( - model_name='alertpluginuserdata', - name='polymorphic_ctype', - field=models.ForeignKey(related_name='polymorphic_cabotapp.alertpluginuserdata_set+', editable=False, to='contenttypes.ContentType', null=True, on_delete=models.CASCADE), - ), - migrations.AlterField( - model_name='statuscheck', - name='polymorphic_ctype', - field=models.ForeignKey(related_name='polymorphic_cabotapp.statuscheck_set+', editable=False, to='contenttypes.ContentType', null=True, on_delete=models.CASCADE), - ), - ] diff --git a/cabot/cabotapp/migrations/0004_auto_20170802_1327.py b/cabot/cabotapp/migrations/0004_auto_20170802_1327.py deleted file mode 100644 index 65878c441..000000000 --- a/cabot/cabotapp/migrations/0004_auto_20170802_1327.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('cabotapp', '0003_auto_20170201_1045'), - ] - - operations = [ - migrations.AddField( - model_name='Service', - name='is_public', - field=models.BooleanField(default=False, help_text=b'The service will be shown in the public home', verbose_name=b'Is Public'), - ), - ] diff --git a/cabot/cabotapp/migrations/0005_auto_20170818_1202.py b/cabot/cabotapp/migrations/0005_auto_20170818_1202.py deleted file mode 100644 index 1eca49be0..000000000 --- a/cabot/cabotapp/migrations/0005_auto_20170818_1202.py +++ /dev/null @@ -1,107 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2017-08-18 12:02 -from __future__ import unicode_literals - -import os - -import django.db.models.deletion -from django.contrib.contenttypes.models import ContentType -from django.db import migrations, models - - -def move_old_jenkins_checks(apps, schema_editor): - db_alias = schema_editor.connection.alias - - JenkinsStatusCheck = apps.get_model("cabotapp", "JenkinsStatusCheck") - JenkinsCheck = apps.get_model("cabotapp", "JenkinsCheck") - JenkinsConfig = apps.get_model("cabotapp", "JenkinsConfig") - - # Due to a polymorphic bug, JenkinsStatusCheck actually returns all status checks - # Use this to filter out the other checks. - jenkins_content_type = ContentType.objects.filter(model="jenkinsstatuscheck").first() - - if jenkins_content_type and not JenkinsStatusCheck.objects.filter(polymorphic_ctype_id=jenkins_content_type.id).exists(): - return - - if not JenkinsConfig.objects.exists(): - JenkinsConfig.objects.create( - name="Default Jenkins", - jenkins_api=os.environ.get("JENKINS_API", "http://jenkins.example.com"), - jenkins_user=os.environ.get("JENKINS_USER", ""), - jenkins_pass=os.environ.get("JENKINS_PASS", ""), - ) - - default_config = JenkinsConfig.objects.first() - - for old_check in JenkinsStatusCheck.objects.all(): - if old_check.polymorphic_ctype_id != jenkins_content_type.id: - continue - new_check = JenkinsCheck( - active=old_check.active, - allowed_num_failures=old_check.allowed_num_failures, - cached_health=old_check.cached_health, - calculated_status=old_check.calculated_status, - check_type=old_check.check_type, - created_by_id=old_check.created_by_id, - debounce=old_check.debounce, - endpoint=old_check.endpoint, - expected_num_hosts=old_check.expected_num_hosts, - frequency=old_check.frequency, - importance=old_check.importance, - last_run=old_check.last_run, - max_queued_build_time=old_check.max_queued_build_time, - metric=old_check.metric, - name=old_check.name, - password=old_check.password, - status_code=old_check.status_code, - text_match=old_check.text_match, - timeout=old_check.timeout, - username=old_check.username, - value=old_check.value, - jenkins_config=default_config, - # For some reason this isn't handled automatically... - # The model is renamed in the next migration so the ctype - # id stays consistent. - polymorphic_ctype_id=old_check.polymorphic_ctype_id - ) - new_check.save(using=db_alias) - new_check.service_set.add(*old_check.service_set.all()) - new_check.instance_set.add(*old_check.instance_set.all()) - new_check.save(using=db_alias) - old_check.delete(using=db_alias) - - -class Migration(migrations.Migration): - - dependencies = [ - ('cabotapp', '0004_auto_20170802_1327'), - ] - - operations = [ - migrations.CreateModel( - name='JenkinsCheck', - fields=[ - ('statuscheck_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='cabotapp.StatusCheck')), - ], - options={ - 'abstract': False, - }, - bases=('cabotapp.statuscheck',), - ), - migrations.CreateModel( - name='JenkinsConfig', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=30)), - ('jenkins_api', models.CharField(max_length=2000)), - ('jenkins_user', models.CharField(max_length=2000)), - ('jenkins_pass', models.CharField(max_length=2000)), - ], - ), - migrations.AddField( - model_name='jenkinscheck', - name='jenkins_config', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cabotapp.JenkinsConfig'), - ), - migrations.RunPython(move_old_jenkins_checks) - ] diff --git a/cabot/cabotapp/migrations/0006_auto_20170821_1000.py b/cabot/cabotapp/migrations/0006_auto_20170821_1000.py deleted file mode 100644 index 764165ff1..000000000 --- a/cabot/cabotapp/migrations/0006_auto_20170821_1000.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2017-08-21 10:00 -from __future__ import unicode_literals - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('cabotapp', '0005_auto_20170818_1202'), - ] - - operations = [ - migrations.DeleteModel( - name='JenkinsStatusCheck', - ), - migrations.RenameModel( - old_name='JenkinsCheck', - new_name='JenkinsStatusCheck', - ) - ] diff --git a/cabot/cabotapp/migrations/0007_statuscheckresult_consecutive_failures.py b/cabot/cabotapp/migrations/0007_statuscheckresult_consecutive_failures.py deleted file mode 100644 index d2cf8dd12..000000000 --- a/cabot/cabotapp/migrations/0007_statuscheckresult_consecutive_failures.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2017-08-24 11:19 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('cabotapp', '0006_auto_20170821_1000'), - ] - - operations = [ - migrations.AddField( - model_name='statuscheckresult', - name='consecutive_failures', - field=models.PositiveIntegerField(null=True), - ), - ] diff --git a/cabot/cabotapp/migrations/0008_auto_20210707_1645.py b/cabot/cabotapp/migrations/0008_auto_20210707_1645.py deleted file mode 100644 index df5ca84d7..000000000 --- a/cabot/cabotapp/migrations/0008_auto_20210707_1645.py +++ /dev/null @@ -1,256 +0,0 @@ -# Generated by Django 3.2.5 on 2021-07-07 16:45 - -from django.conf import settings -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('cabotapp', '0007_statuscheckresult_consecutive_failures'), - ] - - operations = [ - migrations.AlterModelOptions( - name='alertplugin', - options={'base_manager_name': 'objects'}, - ), - migrations.AlterModelOptions( - name='graphitestatuscheck', - options={'base_manager_name': 'objects'}, - ), - migrations.AlterModelOptions( - name='icmpstatuscheck', - options={'base_manager_name': 'objects'}, - ), - migrations.AlterModelOptions( - name='jenkinsstatuscheck', - options={'base_manager_name': 'objects'}, - ), - migrations.AlterModelOptions( - name='statuscheck', - options={'base_manager_name': 'objects', 'ordering': ['name']}, - ), - migrations.AlterField( - model_name='instance', - name='address', - field=models.TextField(blank=True, help_text='Address (IP/Hostname) of service.'), - ), - migrations.AlterField( - model_name='instance', - name='alerts', - field=models.ManyToManyField(blank=True, help_text='Alerts channels through which you wish to be notified', to='cabotapp.AlertPlugin'), - ), - migrations.AlterField( - model_name='instance', - name='alerts_enabled', - field=models.BooleanField(default=True, help_text='Alert when this service is not healthy.'), - ), - migrations.AlterField( - model_name='instance', - name='hackpad_id', - field=models.TextField(blank=True, help_text='Gist, Hackpad or Refheap js embed with recovery instructions e.g. https://you.hackpad.com/some_document.js', null=True, verbose_name='Embedded recovery instructions'), - ), - migrations.AlterField( - model_name='instance', - name='old_overall_status', - field=models.TextField(default='PASSING'), - ), - migrations.AlterField( - model_name='instance', - name='overall_status', - field=models.TextField(default='PASSING'), - ), - migrations.AlterField( - model_name='instance', - name='runbook_link', - field=models.TextField(blank=True, help_text='Link to the service runbook on your wiki.'), - ), - migrations.AlterField( - model_name='instance', - name='status_checks', - field=models.ManyToManyField(blank=True, help_text='Checks used to calculate service status.', to='cabotapp.StatusCheck'), - ), - migrations.AlterField( - model_name='instance', - name='telephone_alert', - field=models.BooleanField(default=False, help_text='Must be enabled, and check importance set to Critical, to receive telephone alerts.'), - ), - migrations.AlterField( - model_name='instance', - name='users_to_notify', - field=models.ManyToManyField(blank=True, help_text='Users who should receive alerts.', to=settings.AUTH_USER_MODEL), - ), - migrations.AlterField( - model_name='instancestatussnapshot', - name='overall_status', - field=models.TextField(default='PASSING'), - ), - migrations.AlterField( - model_name='service', - name='alerts', - field=models.ManyToManyField(blank=True, help_text='Alerts channels through which you wish to be notified', to='cabotapp.AlertPlugin'), - ), - migrations.AlterField( - model_name='service', - name='alerts_enabled', - field=models.BooleanField(default=True, help_text='Alert when this service is not healthy.'), - ), - migrations.AlterField( - model_name='service', - name='hackpad_id', - field=models.TextField(blank=True, help_text='Gist, Hackpad or Refheap js embed with recovery instructions e.g. https://you.hackpad.com/some_document.js', null=True, verbose_name='Embedded recovery instructions'), - ), - migrations.AlterField( - model_name='service', - name='instances', - field=models.ManyToManyField(blank=True, help_text='Instances this service is running on.', to='cabotapp.Instance'), - ), - migrations.AlterField( - model_name='service', - name='is_public', - field=models.BooleanField(default=False, help_text='The service will be shown in the public home', verbose_name='Is Public'), - ), - migrations.AlterField( - model_name='service', - name='old_overall_status', - field=models.TextField(default='PASSING'), - ), - migrations.AlterField( - model_name='service', - name='overall_status', - field=models.TextField(default='PASSING'), - ), - migrations.AlterField( - model_name='service', - name='runbook_link', - field=models.TextField(blank=True, help_text='Link to the service runbook on your wiki.'), - ), - migrations.AlterField( - model_name='service', - name='status_checks', - field=models.ManyToManyField(blank=True, help_text='Checks used to calculate service status.', to='cabotapp.StatusCheck'), - ), - migrations.AlterField( - model_name='service', - name='telephone_alert', - field=models.BooleanField(default=False, help_text='Must be enabled, and check importance set to Critical, to receive telephone alerts.'), - ), - migrations.AlterField( - model_name='service', - name='url', - field=models.TextField(blank=True, help_text='URL of service.'), - ), - migrations.AlterField( - model_name='service', - name='users_to_notify', - field=models.ManyToManyField(blank=True, help_text='Users who should receive alerts.', to=settings.AUTH_USER_MODEL), - ), - migrations.AlterField( - model_name='servicestatussnapshot', - name='overall_status', - field=models.TextField(default='PASSING'), - ), - migrations.AlterField( - model_name='statuscheck', - name='active', - field=models.BooleanField(default=True, help_text='If not active, check will not be used to calculate service status and will not trigger alerts.'), - ), - migrations.AlterField( - model_name='statuscheck', - name='allowed_num_failures', - field=models.IntegerField(default=0, help_text='The maximum number of data series (metrics) you expect to fail. For example, you might be OK with 2 out of 3 webservers having OK load (1 failing), but not 1 out of 3 (2 failing).', null=True), - ), - migrations.AlterField( - model_name='statuscheck', - name='calculated_status', - field=models.CharField(blank=True, choices=[('passing', 'passing'), ('intermittent', 'intermittent'), ('failing', 'failing')], default='passing', max_length=50), - ), - migrations.AlterField( - model_name='statuscheck', - name='check_type', - field=models.CharField(choices=[('>', 'Greater than'), ('>=', 'Greater than or equal'), ('<', 'Less than'), ('<=', 'Less than or equal'), ('==', 'Equal to')], max_length=100, null=True), - ), - migrations.AlterField( - model_name='statuscheck', - name='debounce', - field=models.IntegerField(default=0, help_text='Number of successive failures permitted before check will be marked as failed. Default is 0, i.e. fail on first failure.', null=True), - ), - migrations.AlterField( - model_name='statuscheck', - name='endpoint', - field=models.TextField(help_text='HTTP(S) endpoint to poll.', null=True, validators=[django.core.validators.URLValidator()]), - ), - migrations.AlterField( - model_name='statuscheck', - name='expected_num_hosts', - field=models.IntegerField(default=0, help_text='The minimum number of data series (hosts) you expect to see.', null=True), - ), - migrations.AlterField( - model_name='statuscheck', - name='frequency', - field=models.IntegerField(default=5, help_text='Minutes between each check.'), - ), - migrations.AlterField( - model_name='statuscheck', - name='importance', - field=models.CharField(choices=[('WARNING', 'Warning'), ('ERROR', 'Error'), ('CRITICAL', 'Critical')], default='ERROR', help_text='Severity level of a failure. Critical alerts are for failures you want to wake you up at 2am, Errors are things you can sleep through but need to fix in the morning, and warnings for less important things.', max_length=30), - ), - migrations.AlterField( - model_name='statuscheck', - name='max_queued_build_time', - field=models.IntegerField(blank=True, help_text='Alert if build queued for more than this many minutes.', null=True), - ), - migrations.AlterField( - model_name='statuscheck', - name='metric', - field=models.TextField(help_text='fully.qualified.name of the Graphite metric you want to watch. This can be any valid Graphite expression, including wildcards, multiple hosts, etc.', null=True), - ), - migrations.AlterField( - model_name='statuscheck', - name='password', - field=models.TextField(blank=True, help_text='Basic auth password.', null=True), - ), - migrations.AlterField( - model_name='statuscheck', - name='status_code', - field=models.TextField(default=200, help_text='Status code expected from endpoint.', null=True), - ), - migrations.AlterField( - model_name='statuscheck', - name='text_match', - field=models.TextField(blank=True, help_text='Regex to match against source of page.', null=True), - ), - migrations.AlterField( - model_name='statuscheck', - name='timeout', - field=models.IntegerField(default=30, help_text='Time out after this many seconds.', null=True), - ), - migrations.AlterField( - model_name='statuscheck', - name='username', - field=models.TextField(blank=True, help_text='Basic auth username.', null=True), - ), - migrations.AlterField( - model_name='statuscheck', - name='value', - field=models.TextField(help_text='If this expression evaluates to true, the check will fail (possibly triggering an alert).', null=True), - ), - migrations.AlterField( - model_name='statuscheck', - name='verify_ssl_certificate', - field=models.BooleanField(default=True, help_text='Set to false to allow not try to verify ssl certificates (default True)'), - ), - migrations.AlterField( - model_name='userprofile', - name='hipchat_alias', - field=models.CharField(blank=True, default='', max_length=50), - ), - migrations.AlterField( - model_name='userprofile', - name='mobile_number', - field=models.CharField(blank=True, default='', max_length=20), - ), - ] diff --git a/cabot/cabotapp/migrations/0009_auto_20210719_2116.py b/cabot/cabotapp/migrations/0009_auto_20210719_2116.py deleted file mode 100644 index 351a00123..000000000 --- a/cabot/cabotapp/migrations/0009_auto_20210719_2116.py +++ /dev/null @@ -1,29 +0,0 @@ -# Generated by Django 3.2.5 on 2021-07-20 00:16 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('cabotapp', '0008_auto_20210707_1645'), - ] - - operations = [ - migrations.AlterField( - model_name='Service', - name='status_checks', - field=models.ManyToManyField(blank=True, help_text='Checks used to calculate service status.', to='cabotapp.StatusCheck'), - ), - migrations.AlterField( - model_name='Instance', - name='status_checks', - field=models.ManyToManyField(blank=True, help_text='Checks used to calculate service status.', to='cabotapp.StatusCheck'), - ), - migrations.AlterField( - model_name='StatusCheckResult', - name='status_check', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cabotapp.statuscheck'), - ), - ] diff --git a/cabot/cabotapp/migrations/0010_auto_20210720_1338.py b/cabot/cabotapp/migrations/0010_auto_20210720_1338.py deleted file mode 100644 index 00e9cd47e..000000000 --- a/cabot/cabotapp/migrations/0010_auto_20210720_1338.py +++ /dev/null @@ -1,33 +0,0 @@ -# Generated by Django 3.2.5 on 2021-07-20 16:38 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('cabotapp', '0009_auto_20210719_2116'), - ] - - operations = [ - migrations.RemoveField( - model_name='jenkinsstatuscheck', - name='jenkins_config', - ), - migrations.RemoveField( - model_name='jenkinsstatuscheck', - name='statuscheck_ptr', - ), - migrations.DeleteModel( - name='GraphiteStatusCheck', - ), - migrations.DeleteModel( - name='ICMPStatusCheck', - ), - migrations.DeleteModel( - name='JenkinsConfig', - ), - migrations.DeleteModel( - name='JenkinsStatusCheck', - ), - ] diff --git a/cabot/settings.py b/cabot/settings.py index fab49a246..b75090941 100644 --- a/cabot/settings.py +++ b/cabot/settings.py @@ -4,18 +4,18 @@ from django.urls import reverse_lazy from cabot.settings_utils import environ_get_list, force_bool from cabot.cabot_config import * +import environ +# reading .env file +environ.Env.read_env() settings_dir = os.path.dirname(__file__) PROJECT_ROOT = os.path.abspath(settings_dir) + +DEBUG=os.environ.get('DEBUG', False) -DEBUG = True -if os.environ.get('DEBUG', True)=='True': - DEBUG=True +PROD=os.environ.get('PROD', False) -PROD = False -if os.environ.get('PROD', True)=='True': - PROD=True ADMINS = ( ('Admin', os.environ.get('ADMIN_EMAIL', 'name@example.com')), @@ -28,12 +28,12 @@ DATABASES = { 'default': { - 'ENGINE': 'django.db.backends.postgresql_psycopg2', + 'ENGINE': 'django.db.backends.mysql', 'NAME': os.environ.get('DATABASE_NAME', 'cabot'), 'USER': os.environ.get('DATABASE_USER', 'root'), 'PASSWORD': os.environ.get('DATABASE_PASSWORD', 'root'), - 'HOST': os.environ.get('DATABASE_HOST', '172.26.0.2'), - 'PORT': os.environ.get('DATABASE_PORT', '5432'), + 'HOST': os.environ.get('DATABASE_HOST', '127.0.0.1'), + 'PORT': os.environ.get('DATABASE_PORT', '3306'), } } diff --git a/cabot/static/arachnys/css/base.css b/cabot/static/arachnys/css/base.css new file mode 100644 index 000000000..664adb38b --- /dev/null +++ b/cabot/static/arachnys/css/base.css @@ -0,0 +1,43 @@ +body { + padding-top: 50px; +} +.form-group ul { + list-style-type: none; + padding: 5px 0 0 0; +} +.form-group input[type="radio"] { + margin-top: -3px; +} +tr.warning a { + text-decoration: line-through; +} +#graphite_data_container { + max-height: 200px; + overflow: scroll; +} +.ui-autocomplete { + max-height: 400px; + overflow-y: scroll; + font-size: 10px; +} +.jqstooltip { + display: none; +} +div.dataTables_paginate { + float: right; +} +div.dataTables_info { + float: left; + margin: 20px 0; +} +div.dataTables_length { + float: right; +} +.messages { + margin: auto; + width: 50%; + margin-top: 10px; +} +.navbar-brand > img { + display: inline-block; +} diff --git a/docker-compose copy.yml b/docker-compose copy.yml deleted file mode 100644 index 7e03f776a..000000000 --- a/docker-compose copy.yml +++ /dev/null @@ -1,72 +0,0 @@ -version: '3' -services: - db: - container_name: cabot_pg - image: postgres:alpine - restart: always - environment: - POSTGRES_USER: root - POSTGRES_PASSWORD: root - POSTGRES_DB: test_db - ports: - - "5432:5432" - volumes: - - datavolume:/var/lib/postgresql/data - - pgadmin: - container_name: cabot_pg_admin - image: dpage/pgadmin4 - restart: always - environment: - PGADMIN_DEFAULT_EMAIL: admin@admin.com - PGADMIN_DEFAULT_PASSWORD: root - ports: - - "5050:5050" - - redis: - container_name: cabot_redis - image: redislabs/redismod - restart: always - ports: - - 6379:6379 - - redisinsight: - container_name: cabot_redis_admin - image: redislabs/redisinsight:latest - restart: always - ports: - - '8001:8001' - - web: - build: . - extends: - file: docker-compose-base.yml - service: base - env_file: - - .env - command: python manage.py migrate - command: python manage.py runserver 0.0.0.0:8000 - ports: - - "8000:8000" - links: - - redis - - db - - worker-beat: - extends: - file: docker-compose-base.yml - service: base - env_file: - - .env - command: celery -A cabot worker --beat --scheduler django --loglevel=info - environment: - - SKIP_INIT=1 - - WAIT_FOR_MIGRATIONS=1 - links: - - redis - - db - - -volumes: - datavolume: - diff --git a/docker-compose-base.yml b/docker-compose-base.yml index 9940c5eea..955ff6331 100644 --- a/docker-compose-base.yml +++ b/docker-compose-base.yml @@ -7,4 +7,4 @@ services: volumes: - .:/code env_file: - - .env + - docker.env diff --git a/docker-compose-test.yml b/docker-compose-test.yml deleted file mode 100644 index d2c00a737..000000000 --- a/docker-compose-test.yml +++ /dev/null @@ -1,13 +0,0 @@ -version: '2' -services: - test: - extends: - file: docker-compose-base.yml - service: base - entrypoint: /usr/bin/python - command: manage.py test -v2 - env_file: - - conf/test.env - sut: - image: ubuntu - command: "true" diff --git a/docker-compose.yml b/docker-compose.yml index b54f337ff..60335d0b7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,17 +1,14 @@ version: '3' services: db: - container_name: cabot_pg - image: postgres:alpine - restart: always - environment: - POSTGRES_USER: root - POSTGRES_PASSWORD: root - POSTGRES_DB: test_db + image: mysql ports: - - "5432:5432" - volumes: - - datavolume:/var/lib/postgresql/data + - '3306:3306' + environment: + MYSQL_DATABASE: 'cabot' + MYSQL_ROOT_PASSWORD: 'root' + MYSQL_USER: 'cabot' + MYSQL_PASSWORD: 'cabot' redis: container_name: cabot_redis @@ -21,14 +18,10 @@ services: - 6379:6379 web: - build: . extends: file: docker-compose-base.yml service: base - env_file: - - .env - - command: "python manage.py runserver 0.0.0.0:8000" + command: sh -c "python manage.py migrate && python manage.py runserver 0.0.0.0:8000" ports: - "8000:8000" links: @@ -39,8 +32,6 @@ services: extends: file: docker-compose-base.yml service: base - env_file: - - .env command: celery -A cabot worker --beat --scheduler django --loglevel=info environment: - SKIP_INIT=1 diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh old mode 100755 new mode 100644 index 4731c59cc..274c80c2c --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -1,3 +1,45 @@ #!/bin/bash +set -e -python3 manage.py migrate \ No newline at end of file +function wait_for_broker { + set +e + for try in {1..60} ; do + python -c "from kombu import Connection; x=Connection('$CELERY_BROKER_URL', timeout=1); x.connect()" && break + echo "Waiting for celery broker to respond..." + sleep 1 + done +} + +function wait_for_database { + set +e + for try in {1..60} ; do + python -c "from django.db import connection; connection.connect()" && break + echo "Waiting for database to respond..." + sleep 1 + done +} + +function wait_for_migrations { + set +e + for try in {1..60} ; do + # Kind of ugly but not sure if there's another way to determine if migrations haven't run. + # showmigrations -p returns a checkbox list of migrations, empty checkboxes mean they haven't been run + python manage.py showmigrations -p | grep "\[ \]" &> /dev/null || break + echo "Waiting for database migrations to be run..." + sleep 1 + done +} + + +wait_for_broker +wait_for_database + +if [ -z "$SKIP_INIT" ]; then + /code/bin/build-app +fi + +if [ -n "$WAIT_FOR_MIGRATIONS" ]; then + wait_for_migrations +fi + +exec "$@" diff --git a/docker.env_example b/docker.env_example new file mode 100644 index 000000000..46d4b3102 --- /dev/null +++ b/docker.env_example @@ -0,0 +1,66 @@ +DEBUG=True +PROD=False + +#################### DATABASE CONFIG +#Check diferent options: https://github.com/kennethreitz/dj-database-url + +DATABASE_NAME=cabot +DATABASE_USER=root +DATABASE_PASSWORD=root +DATABASE_HOST=db +DATABASE_PORT=3306 + +#################### PLUGINS - DON'T LEAVE SPACE BETWEEN THEM, ONLY COMMACABOT_PLUGINS=cabot_alert_slack,cabot_check_http,cabot_check_network,cabot_alert_email +CABOT_PLUGINS=cabot_alert_slack,cabot_check_http,cabot_check_network,cabot_alert_email + +#################### GENERAL CONFIG +DJANGO_SETTINGS_MODULE=cabot.settings +LOG_FILE=/dev/null +PORT=8000 +TIME_ZONE=America/Argentina/Buenos_Aires + +#################### CELERY CONFIG +CELERY_BROKER_URL=redis://redis:6379/1 +CELERY_RESULT_BACKEND=redis://redis:6379/1 +CELERY_BEAT_SCHEDULER=django_celery_beat.schedulers:DatabaseScheduler + +#################### DJANGO MAIL CONFIG +ADMIN_EMAIL=example@example.com +CABOT_FROM_EMAIL=example@example.com + +#################### EMAIL ALERT CONFIG +EMAIL_HOST=in-v3.example.com +EMAIL_USER=example +EMAIL_PASSWORD=example + +#################### SLACK CONFIG +SLACK_ALERT_CHANNEL=cabot +SLACK_WEBHOOK_URL=https://discord.com/api/webhooks +SLACK_ICON_URL=http://lorempixel.com/40/40/ + +# Typical SMTP port 587 or 25 configuration (with no SSL/TLS) +EMAIL_PORT=587 +EMAIL_USE_TLS=0 +EMAIL_USE_SSL=0 + +# URL of calendar to synchronise rota with +CALENDAR_ICAL_URL=http://www.google.com/calendar/ical/example.ics + +# Django settings +DJANGO_SECRET_KEY=example + +# User-Agent string used for HTTP checks +HTTP_USER_AGENT=Cabot + +# Used for pointing links back in alerts etc. +WWW_HTTP_HOST=localhost +WWW_SCHEME=http + +# Twilio integration for SMS and telephone alerts +#TWILIO_ACCOUNT_SID=your_account_sid +#TWILIO_AUTH_TOKEN=your_auth_token +#TWILIO_OUTGOING_NUMBER=+14155551234 + +# Hipchat integration +#HIPCHAT_ALERT_ROOM=room_name_or_id +#HIPCHAT_API_KEY=your_hipchat_api_key diff --git a/requiements.txt b/requiements.txt deleted file mode 100644 index a4e44ae1d..000000000 --- a/requiements.txt +++ /dev/null @@ -1,111 +0,0 @@ -amqp==2.6.1 -anyjson==0.3.3 -appdirs==1.4.4 -asgiref==3.4.1 -backcall==0.2.0 -billiard==3.6.4.0 -boto==2.49.0 -boto3==1.17.106 -botocore==1.20.106 -cabot-alert-email==1.4.3 -cabot-alert-hipchat==2.0.3 -cabot-alert-slack==0.8.3 -cabot-alert-twilio==1.3.3 -cached-property==1.5.2 -celery==4.4.2 -certifi==2021.5.30 -cffi==1.14.5 -chardet==4.0.0 -click==7.1.2 -click-didyoumean==0.0.3 -click-plugins==1.1.1 -click-repl==0.2.0 -coffee-compressor-compiler==0.2.0 -coreapi==2.3.3 -coreschema==0.0.4 -coverage==5.5 -cryptography==3.4.7 -decorator==5.0.9 -defusedxml==0.7.1 -dj-database-url==0.5.0 -Django==3.2.5 -django-appconf==1.0.4 -django-auth-ldap==2.4.0 -django-autocomplete-light==3.8.2 -django-bootstrap-form==3.4 -django-compressor==2.4.1 -django-coverage-plugin==2.0.0 -django-filter==2.4.0 -django-jsonify==0.3.0 -django-polymorphic==3.0.0 -djangorestframework==3.12.4 -docutils==0.17.1 -freezegun==1.1.0 -futures==3.1.1 -gevent==21.1.2 -greenlet==1.1.0 -gunicorn==20.1.0 -httplib2==0.19.1 -icalendar==4.0.7 -idna==2.10 -importlib-metadata==4.6.1 -ipdb==0.13.9 -ipython==7.16.1 -ipython-genutils==0.2.0 -isort==5.9.1 -itypes==1.2.0 -jedi==0.18.0 -Jinja2==3.0.1 -jmespath==0.10.0 -kombu==4.6.11 -Markdown==3.3.4 -MarkupSafe==2.0.1 -mock==4.0.3 -multi-key-dict==2.0.3 -oauthlib==3.1.1 -packaging==21.0 -parso==0.8.2 -pbr==5.6.0 -pexpect==4.8.0 -pickleshare==0.7.5 -prompt-toolkit==3.0.19 -psycopg2==2.7.7 -psycopg2-binary==2.9.1 -ptyprocess==0.7.0 -pyasn1==0.4.8 -pyasn1-modules==0.2.8 -pycparser==2.20 -pycurl==7.43.0.6 -PyExecJS==1.5.1 -Pygments==2.9.0 -PyJWT==2.1.0 -pyparsing==2.4.7 -PySocks==1.7.1 -python-dateutil==2.8.1 -python-jenkins==1.7.0 -python-ldap==3.3.1 -python-openid==2.2.5 -python3-openid==3.2.0 -pytz==2021.1 -rcssmin==1.0.6 -redis==3.5.3 -requests==2.25.1 -requests-oauthlib==1.3.0 -rjsmin==1.1.0 -s3transfer==0.4.2 -six==1.16.0 -social-auth-app-django==4.0.0 -social-auth-core==4.1.0 -sqlparse==0.4.1 -toml==0.10.2 -traitlets==4.3.3 -twilio==6.50.1 -typing-extensions==3.10.0.0 -uritemplate==3.0.1 -urllib3==1.26.6 -vine==1.3.0 -wcwidth==0.2.5 -whitenoise==5.2.0 -zipp==3.5.0 -zope.event==4.5.0 -zope.interface==5.4.0 diff --git a/requirements-dev.txt b/requirements-dev.txt deleted file mode 100644 index 9b1bae445..000000000 --- a/requirements-dev.txt +++ /dev/null @@ -1,6 +0,0 @@ -coverage==5.5 -django-coverage-plugin==2.0.0 -freezegun==1.1.0 -mock==4.0.3 -ipdb==0.13.9 -isort==5.9.1 \ No newline at end of file diff --git a/requirements-plugins.txt b/requirements-plugins.txt index e8765ad1e..2482f8b62 100644 --- a/requirements-plugins.txt +++ b/requirements-plugins.txt @@ -1,4 +1,4 @@ git+https://github.com/senzil/cabot-alert-email.git git+https://github.com/senzil/cabot-check-http.git git+https://github.com/senzil/cabot-alert-slack.git -git+https://github.com/senzil/cabot-check-network.git \ No newline at end of file +git+https://github.com/senzil/cabot-check-network.git diff --git a/requirements.txt b/requirements.txt index 80c364b03..7f8489712 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,7 @@ amqp==5.0.6 asgiref==3.4.1 billiard==3.6.4.0 +cabot-alert-slack==0.8.3 cached-property==1.5.2 celery==5.1.2 certifi==2021.5.30 @@ -18,6 +19,7 @@ django-autocomplete-light==3.8.2 django-bootstrap-form==3.4 django-celery-beat==2.2.1 django-compressor==2.4.1 +django-environ==0.4.5 django-filter==2.4.0 django-jsonify==0.3.0 django-polymorphic==3.0.0 @@ -30,13 +32,15 @@ itypes==1.2.0 Jinja2==3.0.1 kombu==5.1.0 MarkupSafe==2.0.1 +mysqlclient==2.0.3 +postgres==3.0.0 prompt-toolkit==3.0.19 -mysqlclient -postgres -psycopg2 +psycopg2==2.9.1 psycopg2-binary==2.9.1 +psycopg2-pool==1.1 python-crontab==2.5.1 python-dateutil==2.8.2 +python-dotenv==0.19.0 pytz==2021.1 rcssmin==1.0.6 redis==3.5.3 @@ -49,4 +53,4 @@ uritemplate==3.0.1 urllib3==1.26.6 vine==5.0.0 wcwidth==0.2.5 -zipp==3.5.0 \ No newline at end of file +zipp==3.5.0 From 759dceb8e30dc107141159177345d05795b492e0 Mon Sep 17 00:00:00 2001 From: Ladrusca Date: Fri, 13 Aug 2021 09:42:24 -0300 Subject: [PATCH 08/24] config pyp --- cabot/.env _example | 66 ++++++++++++++++++++++++++++++++++++++++++++ docker-entrypoint.sh | 4 --- setup.cfg | 0 setup.py | 13 +++++++++ 4 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 cabot/.env _example create mode 100644 setup.cfg create mode 100644 setup.py diff --git a/cabot/.env _example b/cabot/.env _example new file mode 100644 index 000000000..46d4b3102 --- /dev/null +++ b/cabot/.env _example @@ -0,0 +1,66 @@ +DEBUG=True +PROD=False + +#################### DATABASE CONFIG +#Check diferent options: https://github.com/kennethreitz/dj-database-url + +DATABASE_NAME=cabot +DATABASE_USER=root +DATABASE_PASSWORD=root +DATABASE_HOST=db +DATABASE_PORT=3306 + +#################### PLUGINS - DON'T LEAVE SPACE BETWEEN THEM, ONLY COMMACABOT_PLUGINS=cabot_alert_slack,cabot_check_http,cabot_check_network,cabot_alert_email +CABOT_PLUGINS=cabot_alert_slack,cabot_check_http,cabot_check_network,cabot_alert_email + +#################### GENERAL CONFIG +DJANGO_SETTINGS_MODULE=cabot.settings +LOG_FILE=/dev/null +PORT=8000 +TIME_ZONE=America/Argentina/Buenos_Aires + +#################### CELERY CONFIG +CELERY_BROKER_URL=redis://redis:6379/1 +CELERY_RESULT_BACKEND=redis://redis:6379/1 +CELERY_BEAT_SCHEDULER=django_celery_beat.schedulers:DatabaseScheduler + +#################### DJANGO MAIL CONFIG +ADMIN_EMAIL=example@example.com +CABOT_FROM_EMAIL=example@example.com + +#################### EMAIL ALERT CONFIG +EMAIL_HOST=in-v3.example.com +EMAIL_USER=example +EMAIL_PASSWORD=example + +#################### SLACK CONFIG +SLACK_ALERT_CHANNEL=cabot +SLACK_WEBHOOK_URL=https://discord.com/api/webhooks +SLACK_ICON_URL=http://lorempixel.com/40/40/ + +# Typical SMTP port 587 or 25 configuration (with no SSL/TLS) +EMAIL_PORT=587 +EMAIL_USE_TLS=0 +EMAIL_USE_SSL=0 + +# URL of calendar to synchronise rota with +CALENDAR_ICAL_URL=http://www.google.com/calendar/ical/example.ics + +# Django settings +DJANGO_SECRET_KEY=example + +# User-Agent string used for HTTP checks +HTTP_USER_AGENT=Cabot + +# Used for pointing links back in alerts etc. +WWW_HTTP_HOST=localhost +WWW_SCHEME=http + +# Twilio integration for SMS and telephone alerts +#TWILIO_ACCOUNT_SID=your_account_sid +#TWILIO_AUTH_TOKEN=your_auth_token +#TWILIO_OUTGOING_NUMBER=+14155551234 + +# Hipchat integration +#HIPCHAT_ALERT_ROOM=room_name_or_id +#HIPCHAT_API_KEY=your_hipchat_api_key diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 274c80c2c..8c63e1fd1 100644 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -34,10 +34,6 @@ function wait_for_migrations { wait_for_broker wait_for_database -if [ -z "$SKIP_INIT" ]; then - /code/bin/build-app -fi - if [ -n "$WAIT_FOR_MIGRATIONS" ]; then wait_for_migrations fi diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 000000000..e69de29bb diff --git a/setup.py b/setup.py new file mode 100644 index 000000000..f73cdb53d --- /dev/null +++ b/setup.py @@ -0,0 +1,13 @@ +from distutils.core import setup +setup( + name = 'mypackage', + packages = ['mypackage'], # this must be the same as the name above + version = '0.1', + description = 'my description', + author = 'Alejandro Esquiva', + author_email = 'alejandro@geekytheory.com', + url = 'https://github.com/{user_name}/{repo}', # use the URL to the github repo + download_url = 'https://github.com/{user_name}/{repo}/tarball/0.1', + keywords = ['testing', 'logging', 'example'], + classifiers = [], +) From e577900deb5e522c8dfdf23d7f580e1f7f8dda74 Mon Sep 17 00:00:00 2001 From: Ladrusca Date: Fri, 13 Aug 2021 10:29:32 -0300 Subject: [PATCH 09/24] cabot3 --- .gitignore | 2 +- Dockerfile | 16 ++--- MANIFEST.in | 4 +- README.md | 27 -------- cabot/cabotapp/__init__.py | 1 - {cabot => cabot3}/.env _example | 0 {cabot => cabot3}/__init__.py | 0 {cabot => cabot3}/cabot_config.py | 0 cabot3/cabotapp/__init__.py | 1 + {cabot => cabot3}/cabotapp/admin.py | 0 {cabot => cabot3}/cabotapp/alert.py | 0 {cabot => cabot3}/cabotapp/apps.py | 4 +- {cabot => cabot3}/cabotapp/calendar.py | 0 .../cabotapp/migrations/0001_initial.py | 0 .../cabotapp/migrations/__init__.py | 0 {cabot => cabot3}/cabotapp/models/__init__.py | 0 {cabot => cabot3}/cabotapp/models/base.py | 0 {cabot => cabot3}/cabotapp/tasks.py | 0 .../cabotapp/templatetags/__init__.py | 0 .../cabotapp/templatetags/extra.py | 0 {cabot => cabot3}/cabotapp/tests/__init__.py | 0 .../cabotapp/tests/fixtures/__init__.py | 0 .../fixtures/cabot_check_skeleton/__init__.py | 0 .../fixtures/cabot_check_skeleton/plugin.py | 10 +-- .../cabotapp/tests/fixtures/gcal_response.ics | 0 .../tests/fixtures/graphite_avg_response.json | 0 .../fixtures/graphite_null_response.json | 0 .../tests/fixtures/graphite_response.json | 0 .../tests/fixtures/http_response.html | 0 .../tests/fixtures/recurring_response.ics | 0 .../fixtures/recurring_response_complex.ics | 0 .../fixtures/recurring_response_notz.ics | 0 .../cabotapp/tests/test_plugin_settings.py | 8 +-- .../cabotapp/tests/test_setup.py | 0 .../cabotapp/tests/test_urlprefix.py | 0 .../cabotapp/tests/tests_basic.py | 58 +++++++++--------- .../cabotapp/tests/tests_icmp_check.py | 4 +- .../cabotapp/tests/tests_jenkins.py | 20 +++--- {cabot => cabot3}/cabotapp/utils.py | 0 {cabot => cabot3}/cabotapp/views.py | 6 +- {cabot => cabot3}/celery.py | 8 +-- {cabot => cabot3}/context_processors.py | 0 {cabot => cabot3}/entrypoint.py | 2 +- {cabot => cabot3}/rest_urls.py | 2 +- {cabot => cabot3}/settings.py | 10 +-- {cabot => cabot3}/settings_ldap.py | 0 {cabot => cabot3}/settings_utils.py | 0 {cabot => cabot3}/static/404.html | 0 {cabot => cabot3}/static/500.html | 0 {cabot => cabot3}/static/502.html | 0 {cabot => cabot3}/static/503.html | 0 {cabot => cabot3}/static/504.html | 0 .../static/arachnys/css/base.css | 0 .../static/arachnys/css/graph.css | 0 .../static/arachnys/css/morris.css | 0 .../static/arachnys/img/favicon.ico | Bin .../static/arachnys/img/icon_48x48.png | Bin .../static/arachnys/img/icon_96x96.png | Bin {cabot => cabot3}/static/arachnys/js/d3.js | 0 .../static/arachnys/js/morris.js | 0 .../static/arachnys/js/raphael.js | 0 .../static/arachnys/js/rickshaw.js | 0 .../static/bootstrap/css/bootstrap.css | 0 .../static/bootstrap/css/dashboard.css | 0 .../fonts/glyphicons-halflings-regular.eot | Bin .../fonts/glyphicons-halflings-regular.svg | 0 .../fonts/glyphicons-halflings-regular.ttf | Bin .../fonts/glyphicons-halflings-regular.woff | Bin .../fonts/glyphicons-halflings-regular.woff2 | Bin .../static/bootstrap/js/bootstrap.js | 0 .../static/bootstrap/js/jquery-1.10.2.js | 0 {cabot => cabot3}/static/favicon.ico | Bin {cabot => cabot3}/static/robots.txt | 0 .../static/theme/css/bootstrap-chosen.css | 0 .../theme/css/bootstrap-datatables.min.css | 0 .../static/theme/css/bootstrap-responsive.css | 0 .../static/theme/css/bootstrap.css | 0 .../static/theme/css/chosen-sprite.png | Bin .../static/theme/css/chosen-sprite@2x.png | Bin {cabot => cabot3}/static/theme/css/chosen.css | 0 .../theme/css/jquery-ui-1.8.21.custom.css | 0 .../fonts/glyphicons-halflings-regular.eot | Bin .../fonts/glyphicons-halflings-regular.svg | 0 .../fonts/glyphicons-halflings-regular.ttf | Bin .../fonts/glyphicons-halflings-regular.woff | Bin .../fonts/glyphicons-halflings-regular.woff2 | Bin .../static/theme/img/animated-overlay.gif | Bin .../static/theme/img/arrows-active.png | Bin .../static/theme/img/arrows-normal.png | Bin .../static/theme/img/bg-input-focus.png | Bin .../static/theme/img/bg-input.png | Bin .../static/theme/img/bg-login.jpg | Bin {cabot => cabot3}/static/theme/img/bg.jpg | Bin .../static/theme/img/buttons.gif | Bin .../static/theme/img/calendar.gif | Bin .../static/theme/img/chat-left.png | Bin .../static/theme/img/chat-right.png | Bin .../static/theme/img/chosen-sprite.png | Bin .../static/theme/img/close-button-white.png | Bin .../static/theme/img/close-button.png | Bin {cabot => cabot3}/static/theme/img/crop.gif | Bin {cabot => cabot3}/static/theme/img/dbg.jpg | Bin .../static/theme/img/dialogs.png | Bin .../static/theme/img/favicon.ico | Bin .../theme/img/glyphicons-halflings-red.png | Bin .../theme/img/glyphicons-halflings-white.png | Bin .../static/theme/img/glyphicons-halflings.png | Bin .../static/theme/img/i_16_radio.png | Bin .../static/theme/img/icons-big.png | Bin .../static/theme/img/icons-small.png | Bin {cabot => cabot3}/static/theme/img/logo.png | Bin {cabot => cabot3}/static/theme/img/logo20.png | Bin .../static/theme/img/progress.gif | Bin .../static/theme/img/quicklook-bg.png | Bin .../static/theme/img/quicklook-icons.png | Bin {cabot => cabot3}/static/theme/img/resize.png | Bin .../static/theme/img/spinner-mini.gif | Bin {cabot => cabot3}/static/theme/img/sprite.png | Bin .../static/theme/img/toolbar.gif | Bin .../static/theme/img/toolbar.png | Bin .../theme/img/ui-bg_flat_0_aaaaaa_40x100.png | Bin .../theme/img/ui-bg_flat_75_ffffff_40x100.png | Bin .../theme/img/ui-bg_glass_55_fbf9ee_1x400.png | Bin .../theme/img/ui-bg_glass_65_ffffff_1x400.png | Bin .../theme/img/ui-bg_glass_75_dadada_1x400.png | Bin .../theme/img/ui-bg_glass_75_e6e6e6_1x400.png | Bin .../theme/img/ui-bg_glass_95_fef1ec_1x400.png | Bin .../ui-bg_highlight-soft_75_cccccc_1x100.png | Bin .../theme/img/ui-icons_222222_256x240.png | Bin .../theme/img/ui-icons_2e83ff_256x240.png | Bin .../theme/img/ui-icons_454545_256x240.png | Bin .../theme/img/ui-icons_888888_256x240.png | Bin .../theme/img/ui-icons_cd0a0a_256x240.png | Bin .../static/theme/js/bootstrap.js | 0 .../static/theme/js/chosen.jquery.js | 0 {cabot => cabot3}/static/theme/js/custom.js | 0 .../static/theme/js/jquery-ui.js | 0 .../js/jquery.dataTables.bootstrap.min.js | 0 .../static/theme/js/jquery.dataTables.min.js | 0 .../static/theme/js/jquery.sparkline.min.js | 0 .../static/theme/js/jquery.ui.autocomplete.js | 0 .../static/theme/js/jquery.ui.core.js | 0 .../static/theme/js/jquery.ui.position.js | 0 {cabot => cabot3}/templates/404.html | 0 {cabot => cabot3}/templates/500.html | 0 {cabot => cabot3}/templates/base.html | 0 {cabot => cabot3}/templates/base_public.html | 0 .../templates/cabotapp/_base_form.html | 0 .../templates/cabotapp/_instance_list.html | 0 .../templates/cabotapp/_service_list.html | 0 .../cabotapp/_service_public_list.html | 0 .../templates/cabotapp/_statuscheck_list.html | 0 .../templates/cabotapp/about.html | 0 .../cabotapp/alertpluginuserdata_form.html | 0 .../cabotapp/instance_confirm_delete.html | 0 .../templates/cabotapp/instance_detail.html | 0 .../templates/cabotapp/instance_form.html | 0 .../templates/cabotapp/instance_list.html | 0 .../cabotapp/plugin_settings_form.html | 0 .../cabotapp/service_confirm_delete.html | 0 .../templates/cabotapp/service_detail.html | 0 .../templates/cabotapp/service_form.html | 0 .../templates/cabotapp/service_list.html | 0 .../cabotapp/service_public_list.html | 0 .../templates/cabotapp/setup.html | 0 .../templates/cabotapp/shift_list.html | 0 .../cabotapp/statuscheck_confirm_delete.html | 0 .../cabotapp/statuscheck_detail.html | 0 .../templates/cabotapp/statuscheck_form.html | 0 .../templates/cabotapp/statuscheck_list.html | 0 .../cabotapp/statuscheck_report.html | 0 .../cabotapp/statuscheckresult_detail.html | 0 .../templates/cabotapp/subscriptions.html | 0 .../templates/registration/login.html | 0 .../templates/registration/logout.html | 0 .../templates/registration/social_auth.html | 0 {cabot => cabot3}/urls.py | 8 +-- {cabot => cabot3}/version.py | 2 +- {cabot => cabot3}/wsgi.py | 2 +- manage.py | 2 +- setup.cfg | 2 + setup.py | 14 ++--- 182 files changed, 94 insertions(+), 119 deletions(-) delete mode 100644 cabot/cabotapp/__init__.py rename {cabot => cabot3}/.env _example (100%) rename {cabot => cabot3}/__init__.py (100%) rename {cabot => cabot3}/cabot_config.py (100%) create mode 100644 cabot3/cabotapp/__init__.py rename {cabot => cabot3}/cabotapp/admin.py (100%) rename {cabot => cabot3}/cabotapp/alert.py (100%) rename {cabot => cabot3}/cabotapp/apps.py (75%) rename {cabot => cabot3}/cabotapp/calendar.py (100%) rename {cabot => cabot3}/cabotapp/migrations/0001_initial.py (100%) rename {cabot => cabot3}/cabotapp/migrations/__init__.py (100%) rename {cabot => cabot3}/cabotapp/models/__init__.py (100%) rename {cabot => cabot3}/cabotapp/models/base.py (100%) rename {cabot => cabot3}/cabotapp/tasks.py (100%) rename {cabot => cabot3}/cabotapp/templatetags/__init__.py (100%) rename {cabot => cabot3}/cabotapp/templatetags/extra.py (100%) rename {cabot => cabot3}/cabotapp/tests/__init__.py (100%) rename {cabot => cabot3}/cabotapp/tests/fixtures/__init__.py (100%) rename {cabot => cabot3}/cabotapp/tests/fixtures/cabot_check_skeleton/__init__.py (100%) rename {cabot => cabot3}/cabotapp/tests/fixtures/cabot_check_skeleton/plugin.py (74%) rename {cabot => cabot3}/cabotapp/tests/fixtures/gcal_response.ics (100%) rename {cabot => cabot3}/cabotapp/tests/fixtures/graphite_avg_response.json (100%) rename {cabot => cabot3}/cabotapp/tests/fixtures/graphite_null_response.json (100%) rename {cabot => cabot3}/cabotapp/tests/fixtures/graphite_response.json (100%) rename {cabot => cabot3}/cabotapp/tests/fixtures/http_response.html (100%) rename {cabot => cabot3}/cabotapp/tests/fixtures/recurring_response.ics (100%) rename {cabot => cabot3}/cabotapp/tests/fixtures/recurring_response_complex.ics (100%) rename {cabot => cabot3}/cabotapp/tests/fixtures/recurring_response_notz.ics (100%) rename {cabot => cabot3}/cabotapp/tests/test_plugin_settings.py (91%) rename {cabot => cabot3}/cabotapp/tests/test_setup.py (100%) rename {cabot => cabot3}/cabotapp/tests/test_urlprefix.py (100%) rename {cabot => cabot3}/cabotapp/tests/tests_basic.py (96%) rename {cabot => cabot3}/cabotapp/tests/tests_icmp_check.py (94%) rename {cabot => cabot3}/cabotapp/tests/tests_jenkins.py (90%) rename {cabot => cabot3}/cabotapp/utils.py (100%) rename {cabot => cabot3}/cabotapp/views.py (99%) rename {cabot => cabot3}/celery.py (68%) rename {cabot => cabot3}/context_processors.py (100%) rename {cabot => cabot3}/entrypoint.py (66%) rename {cabot => cabot3}/rest_urls.py (98%) rename {cabot => cabot3}/settings.py (98%) rename {cabot => cabot3}/settings_ldap.py (100%) rename {cabot => cabot3}/settings_utils.py (100%) rename {cabot => cabot3}/static/404.html (100%) rename {cabot => cabot3}/static/500.html (100%) rename {cabot => cabot3}/static/502.html (100%) rename {cabot => cabot3}/static/503.html (100%) rename {cabot => cabot3}/static/504.html (100%) rename {cabot => cabot3}/static/arachnys/css/base.css (100%) rename {cabot => cabot3}/static/arachnys/css/graph.css (100%) rename {cabot => cabot3}/static/arachnys/css/morris.css (100%) rename {cabot => cabot3}/static/arachnys/img/favicon.ico (100%) rename {cabot => cabot3}/static/arachnys/img/icon_48x48.png (100%) rename {cabot => cabot3}/static/arachnys/img/icon_96x96.png (100%) rename {cabot => cabot3}/static/arachnys/js/d3.js (100%) rename {cabot => cabot3}/static/arachnys/js/morris.js (100%) rename {cabot => cabot3}/static/arachnys/js/raphael.js (100%) rename {cabot => cabot3}/static/arachnys/js/rickshaw.js (100%) rename {cabot => cabot3}/static/bootstrap/css/bootstrap.css (100%) rename {cabot => cabot3}/static/bootstrap/css/dashboard.css (100%) rename {cabot => cabot3}/static/bootstrap/fonts/glyphicons-halflings-regular.eot (100%) rename {cabot => cabot3}/static/bootstrap/fonts/glyphicons-halflings-regular.svg (100%) rename {cabot => cabot3}/static/bootstrap/fonts/glyphicons-halflings-regular.ttf (100%) rename {cabot => cabot3}/static/bootstrap/fonts/glyphicons-halflings-regular.woff (100%) rename {cabot => cabot3}/static/bootstrap/fonts/glyphicons-halflings-regular.woff2 (100%) rename {cabot => cabot3}/static/bootstrap/js/bootstrap.js (100%) rename {cabot => cabot3}/static/bootstrap/js/jquery-1.10.2.js (100%) rename {cabot => cabot3}/static/favicon.ico (100%) rename {cabot => cabot3}/static/robots.txt (100%) rename {cabot => cabot3}/static/theme/css/bootstrap-chosen.css (100%) rename {cabot => cabot3}/static/theme/css/bootstrap-datatables.min.css (100%) rename {cabot => cabot3}/static/theme/css/bootstrap-responsive.css (100%) rename {cabot => cabot3}/static/theme/css/bootstrap.css (100%) rename {cabot => cabot3}/static/theme/css/chosen-sprite.png (100%) rename {cabot => cabot3}/static/theme/css/chosen-sprite@2x.png (100%) rename {cabot => cabot3}/static/theme/css/chosen.css (100%) rename {cabot => cabot3}/static/theme/css/jquery-ui-1.8.21.custom.css (100%) rename {cabot => cabot3}/static/theme/fonts/glyphicons-halflings-regular.eot (100%) rename {cabot => cabot3}/static/theme/fonts/glyphicons-halflings-regular.svg (100%) rename {cabot => cabot3}/static/theme/fonts/glyphicons-halflings-regular.ttf (100%) rename {cabot => cabot3}/static/theme/fonts/glyphicons-halflings-regular.woff (100%) rename {cabot => cabot3}/static/theme/fonts/glyphicons-halflings-regular.woff2 (100%) rename {cabot => cabot3}/static/theme/img/animated-overlay.gif (100%) rename {cabot => cabot3}/static/theme/img/arrows-active.png (100%) rename {cabot => cabot3}/static/theme/img/arrows-normal.png (100%) rename {cabot => cabot3}/static/theme/img/bg-input-focus.png (100%) rename {cabot => cabot3}/static/theme/img/bg-input.png (100%) rename {cabot => cabot3}/static/theme/img/bg-login.jpg (100%) rename {cabot => cabot3}/static/theme/img/bg.jpg (100%) rename {cabot => cabot3}/static/theme/img/buttons.gif (100%) rename {cabot => cabot3}/static/theme/img/calendar.gif (100%) rename {cabot => cabot3}/static/theme/img/chat-left.png (100%) rename {cabot => cabot3}/static/theme/img/chat-right.png (100%) rename {cabot => cabot3}/static/theme/img/chosen-sprite.png (100%) rename {cabot => cabot3}/static/theme/img/close-button-white.png (100%) rename {cabot => cabot3}/static/theme/img/close-button.png (100%) rename {cabot => cabot3}/static/theme/img/crop.gif (100%) rename {cabot => cabot3}/static/theme/img/dbg.jpg (100%) rename {cabot => cabot3}/static/theme/img/dialogs.png (100%) rename {cabot => cabot3}/static/theme/img/favicon.ico (100%) rename {cabot => cabot3}/static/theme/img/glyphicons-halflings-red.png (100%) rename {cabot => cabot3}/static/theme/img/glyphicons-halflings-white.png (100%) rename {cabot => cabot3}/static/theme/img/glyphicons-halflings.png (100%) rename {cabot => cabot3}/static/theme/img/i_16_radio.png (100%) rename {cabot => cabot3}/static/theme/img/icons-big.png (100%) rename {cabot => cabot3}/static/theme/img/icons-small.png (100%) rename {cabot => cabot3}/static/theme/img/logo.png (100%) rename {cabot => cabot3}/static/theme/img/logo20.png (100%) rename {cabot => cabot3}/static/theme/img/progress.gif (100%) rename {cabot => cabot3}/static/theme/img/quicklook-bg.png (100%) rename {cabot => cabot3}/static/theme/img/quicklook-icons.png (100%) rename {cabot => cabot3}/static/theme/img/resize.png (100%) rename {cabot => cabot3}/static/theme/img/spinner-mini.gif (100%) rename {cabot => cabot3}/static/theme/img/sprite.png (100%) rename {cabot => cabot3}/static/theme/img/toolbar.gif (100%) rename {cabot => cabot3}/static/theme/img/toolbar.png (100%) rename {cabot => cabot3}/static/theme/img/ui-bg_flat_0_aaaaaa_40x100.png (100%) rename {cabot => cabot3}/static/theme/img/ui-bg_flat_75_ffffff_40x100.png (100%) rename {cabot => cabot3}/static/theme/img/ui-bg_glass_55_fbf9ee_1x400.png (100%) rename {cabot => cabot3}/static/theme/img/ui-bg_glass_65_ffffff_1x400.png (100%) rename {cabot => cabot3}/static/theme/img/ui-bg_glass_75_dadada_1x400.png (100%) rename {cabot => cabot3}/static/theme/img/ui-bg_glass_75_e6e6e6_1x400.png (100%) rename {cabot => cabot3}/static/theme/img/ui-bg_glass_95_fef1ec_1x400.png (100%) rename {cabot => cabot3}/static/theme/img/ui-bg_highlight-soft_75_cccccc_1x100.png (100%) rename {cabot => cabot3}/static/theme/img/ui-icons_222222_256x240.png (100%) rename {cabot => cabot3}/static/theme/img/ui-icons_2e83ff_256x240.png (100%) rename {cabot => cabot3}/static/theme/img/ui-icons_454545_256x240.png (100%) rename {cabot => cabot3}/static/theme/img/ui-icons_888888_256x240.png (100%) rename {cabot => cabot3}/static/theme/img/ui-icons_cd0a0a_256x240.png (100%) rename {cabot => cabot3}/static/theme/js/bootstrap.js (100%) rename {cabot => cabot3}/static/theme/js/chosen.jquery.js (100%) rename {cabot => cabot3}/static/theme/js/custom.js (100%) rename {cabot => cabot3}/static/theme/js/jquery-ui.js (100%) rename {cabot => cabot3}/static/theme/js/jquery.dataTables.bootstrap.min.js (100%) rename {cabot => cabot3}/static/theme/js/jquery.dataTables.min.js (100%) rename {cabot => cabot3}/static/theme/js/jquery.sparkline.min.js (100%) rename {cabot => cabot3}/static/theme/js/jquery.ui.autocomplete.js (100%) rename {cabot => cabot3}/static/theme/js/jquery.ui.core.js (100%) rename {cabot => cabot3}/static/theme/js/jquery.ui.position.js (100%) rename {cabot => cabot3}/templates/404.html (100%) rename {cabot => cabot3}/templates/500.html (100%) rename {cabot => cabot3}/templates/base.html (100%) rename {cabot => cabot3}/templates/base_public.html (100%) rename {cabot => cabot3}/templates/cabotapp/_base_form.html (100%) rename {cabot => cabot3}/templates/cabotapp/_instance_list.html (100%) rename {cabot => cabot3}/templates/cabotapp/_service_list.html (100%) rename {cabot => cabot3}/templates/cabotapp/_service_public_list.html (100%) rename {cabot => cabot3}/templates/cabotapp/_statuscheck_list.html (100%) rename {cabot => cabot3}/templates/cabotapp/about.html (100%) rename {cabot => cabot3}/templates/cabotapp/alertpluginuserdata_form.html (100%) rename {cabot => cabot3}/templates/cabotapp/instance_confirm_delete.html (100%) rename {cabot => cabot3}/templates/cabotapp/instance_detail.html (100%) rename {cabot => cabot3}/templates/cabotapp/instance_form.html (100%) rename {cabot => cabot3}/templates/cabotapp/instance_list.html (100%) rename {cabot => cabot3}/templates/cabotapp/plugin_settings_form.html (100%) rename {cabot => cabot3}/templates/cabotapp/service_confirm_delete.html (100%) rename {cabot => cabot3}/templates/cabotapp/service_detail.html (100%) rename {cabot => cabot3}/templates/cabotapp/service_form.html (100%) rename {cabot => cabot3}/templates/cabotapp/service_list.html (100%) rename {cabot => cabot3}/templates/cabotapp/service_public_list.html (100%) rename {cabot => cabot3}/templates/cabotapp/setup.html (100%) rename {cabot => cabot3}/templates/cabotapp/shift_list.html (100%) rename {cabot => cabot3}/templates/cabotapp/statuscheck_confirm_delete.html (100%) rename {cabot => cabot3}/templates/cabotapp/statuscheck_detail.html (100%) rename {cabot => cabot3}/templates/cabotapp/statuscheck_form.html (100%) rename {cabot => cabot3}/templates/cabotapp/statuscheck_list.html (100%) rename {cabot => cabot3}/templates/cabotapp/statuscheck_report.html (100%) rename {cabot => cabot3}/templates/cabotapp/statuscheckresult_detail.html (100%) rename {cabot => cabot3}/templates/cabotapp/subscriptions.html (100%) rename {cabot => cabot3}/templates/registration/login.html (100%) rename {cabot => cabot3}/templates/registration/logout.html (100%) rename {cabot => cabot3}/templates/registration/social_auth.html (100%) rename {cabot => cabot3}/urls.py (97%) rename {cabot => cabot3}/version.py (59%) rename {cabot => cabot3}/wsgi.py (59%) diff --git a/.gitignore b/.gitignore index 34d46dd31..5721c74c4 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,7 @@ dev.db venv/* backups/* -cabot/.collectstatic/ +cabot3/.collectstatic/ node_modules/* .python-eggs/* cabot.egg-info diff --git a/Dockerfile b/Dockerfile index fcf94f261..c4286105e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,8 +25,8 @@ RUN apk update && apk add --no-cache \ # create and activate virtual environment # using final folder name to avoid path issues with packages -RUN python3 -m venv /home/cabot/venv -ENV PATH="/home/cabot/venv/bin:$PATH" +RUN python3 -m venv /home/cabot3/venv +ENV PATH="/home/cabot3/venv/bin:$PATH" ENV PYTHONUNBUFFERED 1 @@ -50,13 +50,13 @@ RUN apk add --no-cache libpq \ mariadb-connector-c-dev RUN adduser -S cabot -COPY --from=builder-image /home/cabot/venv /home/cabot/venv +COPY --from=builder-image /home/cabot3/venv /home/cabot3/venv USER cabot -RUN mkdir /home/cabot/code -WORKDIR /home/cabot/code +RUN mkdir /home/cabot3/code +WORKDIR /home/cabot3/code -COPY ./cabot ./cabot +COPY ./cabot3 ./cabot3 COPY manage.py ./manage.py COPY docker-entrypoint.sh ./docker-entrypoint.sh @@ -66,8 +66,8 @@ EXPOSE 8000 ENV PYTHONUNBUFFERED=1 # activate virtual environment -ENV VIRTUAL_ENV=/home/cabot/venv -ENV PATH="/home/cabot/venv/bin:$PATH" +ENV VIRTUAL_ENV=/home/cabot3/venv +ENV PATH="/home/cabot3/venv/bin:$PATH" # /dev/shm is mapped to shared memory and should be used for gunicorn heartbeat # this will improve performance and avoid random freezes diff --git a/MANIFEST.in b/MANIFEST.in index d46b60e18..1e60a24fe 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,5 @@ -recursive-include cabot/.collectstatic * -recursive-include cabot/templates * +recursive-include cabot3/.collectstatic * +recursive-include cabot3/templates * include requirements.txt include requirements-plugins.txt include requirements-dev.txt diff --git a/README.md b/README.md index 44bc15fec..e8500d432 100644 --- a/README.md +++ b/README.md @@ -49,8 +49,6 @@ Sections: * [Configuration](http://cabotapp.com/use/configuration.html) * [Deployment](http://cabotapp.com/use/deployment.html) * [Services](http://cabotapp.com/use/services.html) -* [Graphite checks](http://cabotapp.com/use/graphite-checks.html) -* [Jenkins checks](http://cabotapp.com/use/jenkins-checks.html) * [HTTP checks](http://cabotapp.com/use/http-checks.html) * [Alerting](http://cabotapp.com/use/alerting.html) * [Users](http://cabotapp.com/use/users.html) @@ -71,14 +69,7 @@ My dog is called Cabot and he loves monitoring things. Mainly the presence of fo It's just a lucky coincidence that his name sounds like he could be an automation tool. -## API -The API has automatically generated documentation available by browsing https://cabot.yourcompany.com/api. The browsable documentation displays example GET requests and lists other allowed HTTP methods. - -To view individual items, append the item `id` to the url. For example, to view `graphite_check` 1, browse: -``` -/api/graphite_checks/1/ -``` ### Authentication @@ -96,24 +87,6 @@ cabotapp | status check | Can add jenkins status check Access the Django admin page at https://cabot.yourcompany.com/admin to add/remove users, change user permissions, add/remove groups for group-based permission control, and change group permissions. -### Sorting and Filtering - -Sorting and filtering can be used by both REST clients and on the browsable API. All fields visible in the browsable API can be used for filtering and sorting. - -Get all `jenkins_checks` with debounce enabled and CRITICAL importance: -``` -https://cabot.yourcompany.com/api/jenkins_checks/?debounce=1&importance=CRITICAL -``` - -Sort `graphite_checks` by `name` field, ascending: -``` -https://cabot.yourcompany.com/api/graphite_checks/?ordering=name -``` - -Sort by `name` field, descending: -``` -https://cabot.yourcompany.com/api/graphite_checks/?ordering=-name -``` Other (non-Cabot specific) examples are available in the [Django REST Framework](http://www.django-rest-framework.org/api-guide/filtering#djangofilterbackend) documentation. diff --git a/cabot/cabotapp/__init__.py b/cabot/cabotapp/__init__.py deleted file mode 100644 index 83efb6de4..000000000 --- a/cabot/cabotapp/__init__.py +++ /dev/null @@ -1 +0,0 @@ -default_app_config = 'cabot.cabotapp.apps.CabotappConfig' diff --git a/cabot/.env _example b/cabot3/.env _example similarity index 100% rename from cabot/.env _example rename to cabot3/.env _example diff --git a/cabot/__init__.py b/cabot3/__init__.py similarity index 100% rename from cabot/__init__.py rename to cabot3/__init__.py diff --git a/cabot/cabot_config.py b/cabot3/cabot_config.py similarity index 100% rename from cabot/cabot_config.py rename to cabot3/cabot_config.py diff --git a/cabot3/cabotapp/__init__.py b/cabot3/cabotapp/__init__.py new file mode 100644 index 000000000..a1702fc96 --- /dev/null +++ b/cabot3/cabotapp/__init__.py @@ -0,0 +1 @@ +default_app_config = 'cabot3.cabotapp.apps.CabotappConfig' diff --git a/cabot/cabotapp/admin.py b/cabot3/cabotapp/admin.py similarity index 100% rename from cabot/cabotapp/admin.py rename to cabot3/cabotapp/admin.py diff --git a/cabot/cabotapp/alert.py b/cabot3/cabotapp/alert.py similarity index 100% rename from cabot/cabotapp/alert.py rename to cabot3/cabotapp/alert.py diff --git a/cabot/cabotapp/apps.py b/cabot3/cabotapp/apps.py similarity index 75% rename from cabot/cabotapp/apps.py rename to cabot3/cabotapp/apps.py index a5853555c..7b31552fc 100644 --- a/cabot/cabotapp/apps.py +++ b/cabot3/cabotapp/apps.py @@ -3,12 +3,12 @@ def post_migrate_callback(**kwargs): - from cabot.cabotapp.alert import update_alert_plugins + from cabot3.cabotapp.alert import update_alert_plugins update_alert_plugins() class CabotappConfig(AppConfig): - name = 'cabot.cabotapp' + name = 'cabot3.cabotapp' def ready(self): post_migrate.connect(post_migrate_callback, sender=self) diff --git a/cabot/cabotapp/calendar.py b/cabot3/cabotapp/calendar.py similarity index 100% rename from cabot/cabotapp/calendar.py rename to cabot3/cabotapp/calendar.py diff --git a/cabot/cabotapp/migrations/0001_initial.py b/cabot3/cabotapp/migrations/0001_initial.py similarity index 100% rename from cabot/cabotapp/migrations/0001_initial.py rename to cabot3/cabotapp/migrations/0001_initial.py diff --git a/cabot/cabotapp/migrations/__init__.py b/cabot3/cabotapp/migrations/__init__.py similarity index 100% rename from cabot/cabotapp/migrations/__init__.py rename to cabot3/cabotapp/migrations/__init__.py diff --git a/cabot/cabotapp/models/__init__.py b/cabot3/cabotapp/models/__init__.py similarity index 100% rename from cabot/cabotapp/models/__init__.py rename to cabot3/cabotapp/models/__init__.py diff --git a/cabot/cabotapp/models/base.py b/cabot3/cabotapp/models/base.py similarity index 100% rename from cabot/cabotapp/models/base.py rename to cabot3/cabotapp/models/base.py diff --git a/cabot/cabotapp/tasks.py b/cabot3/cabotapp/tasks.py similarity index 100% rename from cabot/cabotapp/tasks.py rename to cabot3/cabotapp/tasks.py diff --git a/cabot/cabotapp/templatetags/__init__.py b/cabot3/cabotapp/templatetags/__init__.py similarity index 100% rename from cabot/cabotapp/templatetags/__init__.py rename to cabot3/cabotapp/templatetags/__init__.py diff --git a/cabot/cabotapp/templatetags/extra.py b/cabot3/cabotapp/templatetags/extra.py similarity index 100% rename from cabot/cabotapp/templatetags/extra.py rename to cabot3/cabotapp/templatetags/extra.py diff --git a/cabot/cabotapp/tests/__init__.py b/cabot3/cabotapp/tests/__init__.py similarity index 100% rename from cabot/cabotapp/tests/__init__.py rename to cabot3/cabotapp/tests/__init__.py diff --git a/cabot/cabotapp/tests/fixtures/__init__.py b/cabot3/cabotapp/tests/fixtures/__init__.py similarity index 100% rename from cabot/cabotapp/tests/fixtures/__init__.py rename to cabot3/cabotapp/tests/fixtures/__init__.py diff --git a/cabot/cabotapp/tests/fixtures/cabot_check_skeleton/__init__.py b/cabot3/cabotapp/tests/fixtures/cabot_check_skeleton/__init__.py similarity index 100% rename from cabot/cabotapp/tests/fixtures/cabot_check_skeleton/__init__.py rename to cabot3/cabotapp/tests/fixtures/cabot_check_skeleton/__init__.py diff --git a/cabot/cabotapp/tests/fixtures/cabot_check_skeleton/plugin.py b/cabot3/cabotapp/tests/fixtures/cabot_check_skeleton/plugin.py similarity index 74% rename from cabot/cabotapp/tests/fixtures/cabot_check_skeleton/plugin.py rename to cabot3/cabotapp/tests/fixtures/cabot_check_skeleton/plugin.py index e671a6f59..1d04518fb 100644 --- a/cabot/cabotapp/tests/fixtures/cabot_check_skeleton/plugin.py +++ b/cabot3/cabotapp/tests/fixtures/cabot_check_skeleton/plugin.py @@ -1,9 +1,9 @@ -from cabot.cabotapp.models import StatusCheck -from cabot.cabotapp.views import CheckCreateView -from cabot.cabotapp.views import CheckUpdateView -from cabot.cabotapp.views import StatusCheckForm +from cabot3.cabotapp.models import StatusCheck +from cabot3.cabotapp.views import CheckCreateView +from cabot3.cabotapp.views import CheckUpdateView +from cabot3.cabotapp.views import StatusCheckForm from django.http import HttpResponseRedirect -from django.core.urlresolvers import reverse +from django.urls import reverse class SkeletonStatusCheck(StatusCheck): edit_url_name = 'update-skeleton-check' diff --git a/cabot/cabotapp/tests/fixtures/gcal_response.ics b/cabot3/cabotapp/tests/fixtures/gcal_response.ics similarity index 100% rename from cabot/cabotapp/tests/fixtures/gcal_response.ics rename to cabot3/cabotapp/tests/fixtures/gcal_response.ics diff --git a/cabot/cabotapp/tests/fixtures/graphite_avg_response.json b/cabot3/cabotapp/tests/fixtures/graphite_avg_response.json similarity index 100% rename from cabot/cabotapp/tests/fixtures/graphite_avg_response.json rename to cabot3/cabotapp/tests/fixtures/graphite_avg_response.json diff --git a/cabot/cabotapp/tests/fixtures/graphite_null_response.json b/cabot3/cabotapp/tests/fixtures/graphite_null_response.json similarity index 100% rename from cabot/cabotapp/tests/fixtures/graphite_null_response.json rename to cabot3/cabotapp/tests/fixtures/graphite_null_response.json diff --git a/cabot/cabotapp/tests/fixtures/graphite_response.json b/cabot3/cabotapp/tests/fixtures/graphite_response.json similarity index 100% rename from cabot/cabotapp/tests/fixtures/graphite_response.json rename to cabot3/cabotapp/tests/fixtures/graphite_response.json diff --git a/cabot/cabotapp/tests/fixtures/http_response.html b/cabot3/cabotapp/tests/fixtures/http_response.html similarity index 100% rename from cabot/cabotapp/tests/fixtures/http_response.html rename to cabot3/cabotapp/tests/fixtures/http_response.html diff --git a/cabot/cabotapp/tests/fixtures/recurring_response.ics b/cabot3/cabotapp/tests/fixtures/recurring_response.ics similarity index 100% rename from cabot/cabotapp/tests/fixtures/recurring_response.ics rename to cabot3/cabotapp/tests/fixtures/recurring_response.ics diff --git a/cabot/cabotapp/tests/fixtures/recurring_response_complex.ics b/cabot3/cabotapp/tests/fixtures/recurring_response_complex.ics similarity index 100% rename from cabot/cabotapp/tests/fixtures/recurring_response_complex.ics rename to cabot3/cabotapp/tests/fixtures/recurring_response_complex.ics diff --git a/cabot/cabotapp/tests/fixtures/recurring_response_notz.ics b/cabot3/cabotapp/tests/fixtures/recurring_response_notz.ics similarity index 100% rename from cabot/cabotapp/tests/fixtures/recurring_response_notz.ics rename to cabot3/cabotapp/tests/fixtures/recurring_response_notz.ics diff --git a/cabot/cabotapp/tests/test_plugin_settings.py b/cabot3/cabotapp/tests/test_plugin_settings.py similarity index 91% rename from cabot/cabotapp/tests/test_plugin_settings.py rename to cabot3/cabotapp/tests/test_plugin_settings.py index 236c9aed8..e61e36ce1 100644 --- a/cabot/cabotapp/tests/test_plugin_settings.py +++ b/cabot3/cabotapp/tests/test_plugin_settings.py @@ -5,8 +5,8 @@ from mock import patch -from cabot.cabotapp.alert import AlertPlugin -from cabot.cabotapp.models import Service +from cabot3.cabotapp.alert import AlertPlugin +from cabot3.cabotapp.models import Service class PluginSettingsTest(TestCase): @@ -35,7 +35,7 @@ def test_plugin_disable(self): self.assertEqual(resp.status_code, 200) self.assertIn('Updated Successfully', resp.content) - @patch('cabot.cabotapp.alert.AlertPlugin._send_alert') + @patch('cabot3.cabotapp.alert.AlertPlugin._send_alert') def test_plugin_alert_test(self, fake_send_alert): plugin = AlertPlugin.objects.first() @@ -44,7 +44,7 @@ def test_plugin_alert_test(self, fake_send_alert): self.assertIn('ok', resp.content) fake_send_alert.assert_called() - @patch('cabot.cabotapp.alert.AlertPlugin._send_alert') + @patch('cabot3.cabotapp.alert.AlertPlugin._send_alert') def test_global_alert_test(self, fake_send_alert): service = Service.objects.create( name='Service', diff --git a/cabot/cabotapp/tests/test_setup.py b/cabot3/cabotapp/tests/test_setup.py similarity index 100% rename from cabot/cabotapp/tests/test_setup.py rename to cabot3/cabotapp/tests/test_setup.py diff --git a/cabot/cabotapp/tests/test_urlprefix.py b/cabot3/cabotapp/tests/test_urlprefix.py similarity index 100% rename from cabot/cabotapp/tests/test_urlprefix.py rename to cabot3/cabotapp/tests/test_urlprefix.py diff --git a/cabot/cabotapp/tests/tests_basic.py b/cabot3/cabotapp/tests/tests_basic.py similarity index 96% rename from cabot/cabotapp/tests/tests_basic.py rename to cabot3/cabotapp/tests/tests_basic.py index bce5d0cb3..f10abbd0e 100644 --- a/cabot/cabotapp/tests/tests_basic.py +++ b/cabot3/cabotapp/tests/tests_basic.py @@ -7,16 +7,16 @@ import os import requests -from cabot.cabotapp.graphite import parse_metric -from cabot.cabotapp.alert import update_alert_plugins, AlertPlugin -from cabot.cabotapp.models import ( +from cabot3.cabotapp.graphite import parse_metric +from cabot3.cabotapp.alert import update_alert_plugins, AlertPlugin +from cabot3.cabotapp.models import ( GraphiteStatusCheck, JenkinsStatusCheck, JenkinsConfig, HttpStatusCheck, ICMPStatusCheck, Service, Instance, StatusCheckResult, minimize_targets, ServiceStatusSnapshot, get_custom_check_plugins, create_default_jenkins_config) -from cabot.cabotapp.calendar import get_events -from cabot.cabotapp.views import StatusCheckReportForm -from cabot.cabotapp import tasks +from cabot3.cabotapp.calendar import get_events +from cabot3.cabotapp.views import StatusCheckReportForm +from cabot3.cabotapp import tasks from django.conf import settings from django.contrib.auth.models import Permission from django.contrib.auth.models import User @@ -269,8 +269,8 @@ def test_calculate_service_status(self): self.service.update_status() self.assertEqual(self.service.overall_status, Service.PASSING_STATUS) - @patch('cabot.cabotapp.alert.AlertPlugin._send_alert') - @patch('cabot.cabotapp.alert.AlertPlugin._send_alert_update') + @patch('cabot3.cabotapp.alert.AlertPlugin._send_alert') + @patch('cabot3.cabotapp.alert.AlertPlugin._send_alert_update') @freeze_time('2017-03-02 10:30:43.714759') def test_alert_acknowledgement(self, fake_send_alert_update, fake_send_alert): self.assertEqual(self.service.overall_status, Service.PASSING_STATUS) @@ -305,7 +305,7 @@ def test_alert_acknowledgement(self, fake_send_alert_update, fake_send_alert): self.assertEqual(self.service.unexpired_acknowledgement().user, self.user) fake_send_alert_update.assert_called() - @patch('cabot.cabotapp.graphite.requests.get', fake_graphite_response) + @patch('cabot3.cabotapp.graphite.requests.get', fake_graphite_response) def test_graphite_run(self): checkresults = self.graphite_check.statuscheckresult_set.all() self.assertEqual(len(checkresults), 2) @@ -357,7 +357,7 @@ def test_graphite_run(self): result = checkresults.order_by('-time')[0] self.assertEqual(result.error, u'PROD: 9.16092 > 9.0') - @patch('cabot.cabotapp.graphite.requests.get') + @patch('cabot3.cabotapp.graphite.requests.get') def test_graphite_series_run_exception(self, fake_graphite_series_response): fake_graphite_series_response.side_effect = requests.exceptions.RequestException("some error") jsn = parse_metric('fake.pattern', utcnow=1387818601) @@ -370,14 +370,14 @@ def test_graphite_series_run_exception(self, fake_graphite_series_response): } self.assertEqual(jsn, expected) - @patch('cabot.cabotapp.graphite.requests.get', fake_graphite_series_response) + @patch('cabot3.cabotapp.graphite.requests.get', fake_graphite_series_response) def test_graphite_series_run(self): jsn = parse_metric('fake.pattern', utcnow=1387818601) self.assertLess(abs(jsn['average_value']-53.26), 0.1) self.assertEqual(jsn['series'][0]['max'], 151.0) self.assertEqual(jsn['series'][0]['min'], 0.1) - @patch('cabot.cabotapp.graphite.requests.get', fake_empty_graphite_response) + @patch('cabot3.cabotapp.graphite.requests.get', fake_empty_graphite_response) def test_graphite_empty_run(self): checkresults = self.graphite_check.statuscheckresult_set.all() self.assertEqual(len(checkresults), 2) @@ -396,7 +396,7 @@ def test_graphite_empty_run(self): self.assertEqual(self.graphite_check.calculated_status, Service.CALCULATED_FAILING_STATUS) - @patch('cabot.cabotapp.graphite.requests.get', fake_slow_graphite_response) + @patch('cabot3.cabotapp.graphite.requests.get', fake_slow_graphite_response) def test_graphite_timing(self): checkresults = self.graphite_check.statuscheckresult_set.all() self.assertEqual(len(checkresults), 2) @@ -406,7 +406,7 @@ def test_graphite_timing(self): self.assertTrue(self.graphite_check.last_result().succeeded) self.assertGreater(list(checkresults)[-1].took, 0.0) - @patch('cabot.cabotapp.models.jenkins_check_plugin.get_job_status') + @patch('cabot3.cabotapp.models.jenkins_check_plugin.get_job_status') def test_jenkins_run(self, mock_get_job_status): mock_get_job_status.return_value = fake_jenkins_response() checkresults = self.jenkins_check.statuscheckresult_set.all() @@ -416,7 +416,7 @@ def test_jenkins_run(self, mock_get_job_status): self.assertEqual(len(checkresults), 1) self.assertFalse(self.jenkins_check.last_result().succeeded) - @patch('cabot.cabotapp.models.jenkins_check_plugin.get_job_status') + @patch('cabot3.cabotapp.models.jenkins_check_plugin.get_job_status') def test_jenkins_blocked_build(self, mock_get_job_status): mock_get_job_status.return_value = jenkins_blocked_response() checkresults = self.jenkins_check.statuscheckresult_set.all() @@ -426,7 +426,7 @@ def test_jenkins_blocked_build(self, mock_get_job_status): self.assertEqual(len(checkresults), 1) self.assertFalse(self.jenkins_check.last_result().succeeded) - @patch('cabot.cabotapp.models.jenkins_check_plugin.get_job_status', throws_timeout) + @patch('cabot3.cabotapp.models.jenkins_check_plugin.get_job_status', throws_timeout) def test_timeout_handling_in_jenkins(self): """This works because we are effectively patching requests.get globally, including in jenkinsapi.""" checkresults = self.jenkins_check.statuscheckresult_set.all() @@ -438,7 +438,7 @@ def test_timeout_handling_in_jenkins(self): self.assertIn(u'Error fetching from Jenkins - Ņ„иĐēŅ‚ивĐŊĐ°Ņ ĐžŅˆĐ¸ĐąĐēĐ°', self.jenkins_check.last_result().error) - @patch('cabot.cabotapp.models.requests.get', fake_http_200_response) + @patch('cabot3.cabotapp.models.requests.get', fake_http_200_response) def test_http_run(self): checkresults = self.http_check.statuscheckresult_set.all() self.assertEqual(len(checkresults), 0) @@ -464,7 +464,7 @@ def test_http_run(self): self.assertIn(u'Failed to find match regex', self.http_check.last_result().error) - @patch('cabot.cabotapp.models.requests.get', throws_timeout) + @patch('cabot3.cabotapp.models.requests.get', throws_timeout) def test_timeout_handling_in_http(self): checkresults = self.http_check.statuscheckresult_set.all() self.assertEqual(len(checkresults), 0) @@ -475,7 +475,7 @@ def test_timeout_handling_in_http(self): self.assertIn(u'Request error occurred: Ņ„иĐēŅ‚ивĐŊĐ°Ņ ĐžŅˆĐ¸ĐąĐēĐ° innit', self.http_check.last_result().error) - @patch('cabot.cabotapp.models.requests.get', fake_http_404_response) + @patch('cabot3.cabotapp.models.requests.get', fake_http_404_response) def test_http_run_bad_resp(self): checkresults = self.http_check.statuscheckresult_set.all() self.assertEqual(len(checkresults), 0) @@ -513,12 +513,12 @@ def test_duplicate_instance(self): class TestDutyRota(LocalTestCase): - @patch('cabot.cabotapp.models.requests.get', fake_gcal_response) + @patch('cabot3.cabotapp.models.requests.get', fake_gcal_response) def test_duty_rota(self): events = get_events() self.assertEqual(events[0]['summary'], 'troels') - @patch('cabot.cabotapp.models.requests.get', fake_recurring_response) + @patch('cabot3.cabotapp.models.requests.get', fake_recurring_response) def test_duty_rota_recurring(self): events = get_events() events.sort(key=lambda ev: ev['start']) @@ -531,7 +531,7 @@ def test_duty_rota_recurring(self): else: curr_summ = 'foo' - @patch('cabot.cabotapp.models.requests.get', fake_recurring_response_notz) + @patch('cabot3.cabotapp.models.requests.get', fake_recurring_response_notz) def test_duty_rota_recurring_notz(self): events = get_events() events.sort(key=lambda ev: ev['start']) @@ -544,7 +544,7 @@ def test_duty_rota_recurring_notz(self): else: curr_summ = 'foo' - @patch('cabot.cabotapp.models.requests.get', + @patch('cabot3.cabotapp.models.requests.get', fake_recurring_response_complex) def test_duty_rota_recurring_complex(self): events = get_events() @@ -1098,7 +1098,7 @@ def test_users_to_notify(self): self.assertEqual(self.service.users_to_notify.all().count(), 1) self.assertEqual(self.service.users_to_notify.get().username, self.user.username) - @patch('cabot.cabotapp.alert.AlertPlugin._send_alert') + @patch('cabot3.cabotapp.alert.AlertPlugin._send_alert') def test_alert(self, fake_send_alert): self.service.alert() self.assertEqual(fake_send_alert.call_count, 1) @@ -1115,7 +1115,7 @@ def trigger_failing_check(self, check): check.last_run = timezone.now() check.save() - @patch('cabot.cabotapp.alert.AlertPlugin._send_alert') + @patch('cabot3.cabotapp.alert.AlertPlugin._send_alert') def test_alert_increasing_severity(self, fake_send_alert): self.trigger_failing_check(self.warning_http_check) self.assertEqual(fake_send_alert.call_count, 1) @@ -1126,7 +1126,7 @@ def test_alert_increasing_severity(self, fake_send_alert): self.trigger_failing_check(self.critical_http_check) self.assertEqual(fake_send_alert.call_count, 3) - @patch('cabot.cabotapp.alert.AlertPlugin._send_alert') + @patch('cabot3.cabotapp.alert.AlertPlugin._send_alert') def test_alert_decreasing_severity(self, fake_send_alert): self.trigger_failing_check(self.critical_http_check) self.assertEqual(fake_send_alert.call_count, 1) @@ -1137,7 +1137,7 @@ def test_alert_decreasing_severity(self, fake_send_alert): self.trigger_failing_check(self.warning_http_check) self.assertEqual(fake_send_alert.call_count, 1) - @patch('cabot.cabotapp.alert.AlertPlugin._send_alert') + @patch('cabot3.cabotapp.alert.AlertPlugin._send_alert') def test_alert_alternating_severity(self, fake_send_alert): self.trigger_failing_check(self.error_http_check) self.assertEqual(fake_send_alert.call_count, 1) @@ -1217,7 +1217,7 @@ def test_cleanup_batch(self): self.assertEqual(StatusCheckResult.objects.all().count(), initial_results) def test_cleanup_single_batch(self): - with patch('cabot.cabotapp.tasks.clean_db.apply_async'): + with patch('cabot3.cabotapp.tasks.clean_db.apply_async'): initial_results = StatusCheckResult.objects.all().count() for i in range(2): @@ -1232,7 +1232,7 @@ def test_cleanup_single_batch(self): tasks.clean_db(batch_size=1) self.assertEqual(StatusCheckResult.objects.all().count(), initial_results + 1) - @patch('cabot.cabotapp.tasks.clean_db.apply_async') + @patch('cabot3.cabotapp.tasks.clean_db.apply_async') def test_infinite_cleanup_loop(self, mocked_apply_async): """ There is a potential for the cleanup task to constantly call itself diff --git a/cabot/cabotapp/tests/tests_icmp_check.py b/cabot3/cabotapp/tests/tests_icmp_check.py similarity index 94% rename from cabot/cabotapp/tests/tests_icmp_check.py rename to cabot3/cabotapp/tests/tests_icmp_check.py index 40311c6b9..0e40c9fc9 100644 --- a/cabot/cabotapp/tests/tests_icmp_check.py +++ b/cabot3/cabotapp/tests/tests_icmp_check.py @@ -2,7 +2,7 @@ from mock import patch -from cabot.cabotapp.models import ( +from cabot3.cabotapp.models import ( ICMPStatusCheck, Instance, Service, @@ -26,7 +26,7 @@ def setUp(self): self.instance.status_checks.add( self.icmp_check) - self.patch = patch('cabot.cabotapp.models.subprocess.check_output', autospec=True) + self.patch = patch('cabot3.cabotapp.models.subprocess.check_output', autospec=True) self.mock_check_output = self.patch.start() def tearDown(self): diff --git a/cabot/cabotapp/tests/tests_jenkins.py b/cabot3/cabotapp/tests/tests_jenkins.py similarity index 90% rename from cabot/cabotapp/tests/tests_jenkins.py rename to cabot3/cabotapp/tests/tests_jenkins.py index 8983e6cd6..796fce359 100644 --- a/cabot/cabotapp/tests/tests_jenkins.py +++ b/cabot3/cabotapp/tests/tests_jenkins.py @@ -4,9 +4,9 @@ from datetime import timedelta import jenkins -from cabot.cabotapp import jenkins as cabot_jenkins -from cabot.cabotapp.models import JenkinsConfig -from cabot.cabotapp.models.jenkins_check_plugin import JenkinsStatusCheck +from cabot3.cabotapp import jenkins as cabot_jenkins +from cabot3.cabotapp.models import JenkinsConfig +from cabot3.cabotapp.models.jenkins_check_plugin import JenkinsStatusCheck from django.utils import timezone from freezegun import freeze_time from mock import create_autospec, patch @@ -42,7 +42,7 @@ def setUp(self): self.mock_config = create_autospec(JenkinsConfig) - @patch("cabot.cabotapp.jenkins._get_jenkins_client") + @patch("cabot3.cabotapp.jenkins._get_jenkins_client") def test_job_passing(self, mock_jenkins): mock_jenkins.return_value = self.mock_client @@ -58,7 +58,7 @@ def test_job_passing(self, mock_jenkins): } self.assertEqual(status, expected) - @patch("cabot.cabotapp.jenkins._get_jenkins_client") + @patch("cabot3.cabotapp.jenkins._get_jenkins_client") def test_job_failing(self, mock_jenkins): mock_jenkins.return_value = self.mock_client @@ -83,7 +83,7 @@ def test_job_failing(self, mock_jenkins): self.assertFalse(result.succeeded) @freeze_time('2017-03-02 10:30') - @patch("cabot.cabotapp.jenkins._get_jenkins_client") + @patch("cabot3.cabotapp.jenkins._get_jenkins_client") def test_job_queued_last_succeeded(self, mock_jenkins): mock_jenkins.return_value = self.mock_client self.job[u'lastBuild'] = {u'number': 13} @@ -108,7 +108,7 @@ def test_job_queued_last_succeeded(self, mock_jenkins): self.assertEqual(status, expected) @freeze_time('2017-03-02 10:30') - @patch("cabot.cabotapp.jenkins._get_jenkins_client") + @patch("cabot3.cabotapp.jenkins._get_jenkins_client") def test_job_queued_last_failed(self, mock_jenkins): mock_jenkins.return_value = self.mock_client self.job[u'lastBuild'] = {u'number': 13} @@ -132,7 +132,7 @@ def test_job_queued_last_failed(self, mock_jenkins): } self.assertEqual(status, expected) - @patch("cabot.cabotapp.jenkins._get_jenkins_client") + @patch("cabot3.cabotapp.jenkins._get_jenkins_client") def test_job_unknown(self, mock_jenkins): self.mock_client.get_job_info.side_effect = jenkins.NotFoundException() mock_jenkins.return_value = self.mock_client @@ -148,7 +148,7 @@ def test_job_unknown(self, mock_jenkins): } self.assertEqual(status, expected) - @patch("cabot.cabotapp.jenkins._get_jenkins_client") + @patch("cabot3.cabotapp.jenkins._get_jenkins_client") def test_job_no_build(self, mock_jenkins): unbuilt_job = { u'inQueue': False, @@ -163,7 +163,7 @@ def test_job_no_build(self, mock_jenkins): with self.assertRaises(Exception): cabot_jenkins.get_job_status(self.mock_config, 'job-unbuilt') - @patch("cabot.cabotapp.jenkins._get_jenkins_client") + @patch("cabot3.cabotapp.jenkins._get_jenkins_client") def test_job_no_good_build(self, mock_jenkins): self.mock_client.get_job_info.return_value = { u'inQueue': False, diff --git a/cabot/cabotapp/utils.py b/cabot3/cabotapp/utils.py similarity index 100% rename from cabot/cabotapp/utils.py rename to cabot3/cabotapp/utils.py diff --git a/cabot/cabotapp/views.py b/cabot3/cabotapp/views.py similarity index 99% rename from cabot/cabotapp/views.py rename to cabot3/cabotapp/views.py index a6a1d1995..7957e1f97 100644 --- a/cabot/cabotapp/views.py +++ b/cabot3/cabotapp/views.py @@ -5,8 +5,8 @@ import os import requests from .alert import AlertPlugin, AlertPluginUserData -from cabot.cabotapp import alert -from cabot.cabotapp.utils import cabot_needs_setup +from cabot3.cabotapp import alert +from cabot3.cabotapp.utils import cabot_needs_setup from dateutil.relativedelta import relativedelta from django import forms from django.conf import settings @@ -939,7 +939,7 @@ def checks_run_recently(request): def about(request): """ Very simple about page """ - from cabot import version + from cabot3 import version return render(request, 'cabotapp/about.html', { 'cabot_version': version, diff --git a/cabot/celery.py b/cabot3/celery.py similarity index 68% rename from cabot/celery.py rename to cabot3/celery.py index 51910e09d..03fa6b6ae 100644 --- a/cabot/celery.py +++ b/cabot3/celery.py @@ -7,7 +7,7 @@ from celery import Celery -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'cabot.settings') +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'cabot3.settings') app = Celery('cabot') @@ -16,15 +16,15 @@ app.conf.beat_schedule = { 'run-all-checks': { - 'task': 'cabot.cabotapp.tasks.run_all_checks', + 'task': 'cabot3.cabotapp.tasks.run_all_checks', 'schedule': timedelta(seconds=60), }, 'update-shifts': { - 'task': 'cabot.cabotapp.tasks.update_shifts', + 'task': 'cabot3.cabotapp.tasks.update_shifts', 'schedule': timedelta(seconds=1800), }, 'clean-db': { - 'task': 'cabot.cabotapp.tasks.clean_db', + 'task': 'cabot3.cabotapp.tasks.clean_db', 'schedule': timedelta(seconds=120), }, } \ No newline at end of file diff --git a/cabot/context_processors.py b/cabot3/context_processors.py similarity index 100% rename from cabot/context_processors.py rename to cabot3/context_processors.py diff --git a/cabot/entrypoint.py b/cabot3/entrypoint.py similarity index 66% rename from cabot/entrypoint.py rename to cabot3/entrypoint.py index dbe4ef916..caaf9be55 100644 --- a/cabot/entrypoint.py +++ b/cabot3/entrypoint.py @@ -3,7 +3,7 @@ def main(): - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cabot.settings") + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cabot3.settings") from django.core.management import execute_from_command_line diff --git a/cabot/rest_urls.py b/cabot3/rest_urls.py similarity index 98% rename from cabot/rest_urls.py rename to cabot3/rest_urls.py index 58f53408b..7244e4553 100644 --- a/cabot/rest_urls.py +++ b/cabot3/rest_urls.py @@ -4,7 +4,7 @@ from django.contrib.auth import models as django_models from polymorphic.models import PolymorphicModel -from cabot.cabotapp import models, alert +from cabot3.cabotapp import models, alert from rest_framework import routers, serializers, viewsets, mixins import logging diff --git a/cabot/settings.py b/cabot3/settings.py similarity index 98% rename from cabot/settings.py rename to cabot3/settings.py index b75090941..e42c7c709 100644 --- a/cabot/settings.py +++ b/cabot3/settings.py @@ -2,8 +2,8 @@ import re from django.conf import settings from django.urls import reverse_lazy -from cabot.settings_utils import environ_get_list, force_bool -from cabot.cabot_config import * +from cabot3.settings_utils import environ_get_list, force_bool +from cabot3.cabot_config import * import environ # reading .env file @@ -126,7 +126,7 @@ 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', - 'cabot.context_processors.global_settings', + 'cabot3.context_processors.global_settings', ], 'debug': force_bool(os.environ.get('TEMPLATE_DEBUG', False)) }, @@ -144,7 +144,7 @@ 'django.middleware.clickjacking.XFrameOptionsMiddleware', ) -ROOT_URLCONF = 'cabot.urls' +ROOT_URLCONF = 'cabot3.urls' INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', @@ -158,7 +158,7 @@ 'compressor', 'polymorphic', 'jsonify', - 'cabot.cabotapp', + 'cabot3.cabotapp', 'rest_framework', 'dal', 'dal_select2', diff --git a/cabot/settings_ldap.py b/cabot3/settings_ldap.py similarity index 100% rename from cabot/settings_ldap.py rename to cabot3/settings_ldap.py diff --git a/cabot/settings_utils.py b/cabot3/settings_utils.py similarity index 100% rename from cabot/settings_utils.py rename to cabot3/settings_utils.py diff --git a/cabot/static/404.html b/cabot3/static/404.html similarity index 100% rename from cabot/static/404.html rename to cabot3/static/404.html diff --git a/cabot/static/500.html b/cabot3/static/500.html similarity index 100% rename from cabot/static/500.html rename to cabot3/static/500.html diff --git a/cabot/static/502.html b/cabot3/static/502.html similarity index 100% rename from cabot/static/502.html rename to cabot3/static/502.html diff --git a/cabot/static/503.html b/cabot3/static/503.html similarity index 100% rename from cabot/static/503.html rename to cabot3/static/503.html diff --git a/cabot/static/504.html b/cabot3/static/504.html similarity index 100% rename from cabot/static/504.html rename to cabot3/static/504.html diff --git a/cabot/static/arachnys/css/base.css b/cabot3/static/arachnys/css/base.css similarity index 100% rename from cabot/static/arachnys/css/base.css rename to cabot3/static/arachnys/css/base.css diff --git a/cabot/static/arachnys/css/graph.css b/cabot3/static/arachnys/css/graph.css similarity index 100% rename from cabot/static/arachnys/css/graph.css rename to cabot3/static/arachnys/css/graph.css diff --git a/cabot/static/arachnys/css/morris.css b/cabot3/static/arachnys/css/morris.css similarity index 100% rename from cabot/static/arachnys/css/morris.css rename to cabot3/static/arachnys/css/morris.css diff --git a/cabot/static/arachnys/img/favicon.ico b/cabot3/static/arachnys/img/favicon.ico similarity index 100% rename from cabot/static/arachnys/img/favicon.ico rename to cabot3/static/arachnys/img/favicon.ico diff --git a/cabot/static/arachnys/img/icon_48x48.png b/cabot3/static/arachnys/img/icon_48x48.png similarity index 100% rename from cabot/static/arachnys/img/icon_48x48.png rename to cabot3/static/arachnys/img/icon_48x48.png diff --git a/cabot/static/arachnys/img/icon_96x96.png b/cabot3/static/arachnys/img/icon_96x96.png similarity index 100% rename from cabot/static/arachnys/img/icon_96x96.png rename to cabot3/static/arachnys/img/icon_96x96.png diff --git a/cabot/static/arachnys/js/d3.js b/cabot3/static/arachnys/js/d3.js similarity index 100% rename from cabot/static/arachnys/js/d3.js rename to cabot3/static/arachnys/js/d3.js diff --git a/cabot/static/arachnys/js/morris.js b/cabot3/static/arachnys/js/morris.js similarity index 100% rename from cabot/static/arachnys/js/morris.js rename to cabot3/static/arachnys/js/morris.js diff --git a/cabot/static/arachnys/js/raphael.js b/cabot3/static/arachnys/js/raphael.js similarity index 100% rename from cabot/static/arachnys/js/raphael.js rename to cabot3/static/arachnys/js/raphael.js diff --git a/cabot/static/arachnys/js/rickshaw.js b/cabot3/static/arachnys/js/rickshaw.js similarity index 100% rename from cabot/static/arachnys/js/rickshaw.js rename to cabot3/static/arachnys/js/rickshaw.js diff --git a/cabot/static/bootstrap/css/bootstrap.css b/cabot3/static/bootstrap/css/bootstrap.css similarity index 100% rename from cabot/static/bootstrap/css/bootstrap.css rename to cabot3/static/bootstrap/css/bootstrap.css diff --git a/cabot/static/bootstrap/css/dashboard.css b/cabot3/static/bootstrap/css/dashboard.css similarity index 100% rename from cabot/static/bootstrap/css/dashboard.css rename to cabot3/static/bootstrap/css/dashboard.css diff --git a/cabot/static/bootstrap/fonts/glyphicons-halflings-regular.eot b/cabot3/static/bootstrap/fonts/glyphicons-halflings-regular.eot similarity index 100% rename from cabot/static/bootstrap/fonts/glyphicons-halflings-regular.eot rename to cabot3/static/bootstrap/fonts/glyphicons-halflings-regular.eot diff --git a/cabot/static/bootstrap/fonts/glyphicons-halflings-regular.svg b/cabot3/static/bootstrap/fonts/glyphicons-halflings-regular.svg similarity index 100% rename from cabot/static/bootstrap/fonts/glyphicons-halflings-regular.svg rename to cabot3/static/bootstrap/fonts/glyphicons-halflings-regular.svg diff --git a/cabot/static/bootstrap/fonts/glyphicons-halflings-regular.ttf b/cabot3/static/bootstrap/fonts/glyphicons-halflings-regular.ttf similarity index 100% rename from cabot/static/bootstrap/fonts/glyphicons-halflings-regular.ttf rename to cabot3/static/bootstrap/fonts/glyphicons-halflings-regular.ttf diff --git a/cabot/static/bootstrap/fonts/glyphicons-halflings-regular.woff b/cabot3/static/bootstrap/fonts/glyphicons-halflings-regular.woff similarity index 100% rename from cabot/static/bootstrap/fonts/glyphicons-halflings-regular.woff rename to cabot3/static/bootstrap/fonts/glyphicons-halflings-regular.woff diff --git a/cabot/static/bootstrap/fonts/glyphicons-halflings-regular.woff2 b/cabot3/static/bootstrap/fonts/glyphicons-halflings-regular.woff2 similarity index 100% rename from cabot/static/bootstrap/fonts/glyphicons-halflings-regular.woff2 rename to cabot3/static/bootstrap/fonts/glyphicons-halflings-regular.woff2 diff --git a/cabot/static/bootstrap/js/bootstrap.js b/cabot3/static/bootstrap/js/bootstrap.js similarity index 100% rename from cabot/static/bootstrap/js/bootstrap.js rename to cabot3/static/bootstrap/js/bootstrap.js diff --git a/cabot/static/bootstrap/js/jquery-1.10.2.js b/cabot3/static/bootstrap/js/jquery-1.10.2.js similarity index 100% rename from cabot/static/bootstrap/js/jquery-1.10.2.js rename to cabot3/static/bootstrap/js/jquery-1.10.2.js diff --git a/cabot/static/favicon.ico b/cabot3/static/favicon.ico similarity index 100% rename from cabot/static/favicon.ico rename to cabot3/static/favicon.ico diff --git a/cabot/static/robots.txt b/cabot3/static/robots.txt similarity index 100% rename from cabot/static/robots.txt rename to cabot3/static/robots.txt diff --git a/cabot/static/theme/css/bootstrap-chosen.css b/cabot3/static/theme/css/bootstrap-chosen.css similarity index 100% rename from cabot/static/theme/css/bootstrap-chosen.css rename to cabot3/static/theme/css/bootstrap-chosen.css diff --git a/cabot/static/theme/css/bootstrap-datatables.min.css b/cabot3/static/theme/css/bootstrap-datatables.min.css similarity index 100% rename from cabot/static/theme/css/bootstrap-datatables.min.css rename to cabot3/static/theme/css/bootstrap-datatables.min.css diff --git a/cabot/static/theme/css/bootstrap-responsive.css b/cabot3/static/theme/css/bootstrap-responsive.css similarity index 100% rename from cabot/static/theme/css/bootstrap-responsive.css rename to cabot3/static/theme/css/bootstrap-responsive.css diff --git a/cabot/static/theme/css/bootstrap.css b/cabot3/static/theme/css/bootstrap.css similarity index 100% rename from cabot/static/theme/css/bootstrap.css rename to cabot3/static/theme/css/bootstrap.css diff --git a/cabot/static/theme/css/chosen-sprite.png b/cabot3/static/theme/css/chosen-sprite.png similarity index 100% rename from cabot/static/theme/css/chosen-sprite.png rename to cabot3/static/theme/css/chosen-sprite.png diff --git a/cabot/static/theme/css/chosen-sprite@2x.png b/cabot3/static/theme/css/chosen-sprite@2x.png similarity index 100% rename from cabot/static/theme/css/chosen-sprite@2x.png rename to cabot3/static/theme/css/chosen-sprite@2x.png diff --git a/cabot/static/theme/css/chosen.css b/cabot3/static/theme/css/chosen.css similarity index 100% rename from cabot/static/theme/css/chosen.css rename to cabot3/static/theme/css/chosen.css diff --git a/cabot/static/theme/css/jquery-ui-1.8.21.custom.css b/cabot3/static/theme/css/jquery-ui-1.8.21.custom.css similarity index 100% rename from cabot/static/theme/css/jquery-ui-1.8.21.custom.css rename to cabot3/static/theme/css/jquery-ui-1.8.21.custom.css diff --git a/cabot/static/theme/fonts/glyphicons-halflings-regular.eot b/cabot3/static/theme/fonts/glyphicons-halflings-regular.eot similarity index 100% rename from cabot/static/theme/fonts/glyphicons-halflings-regular.eot rename to cabot3/static/theme/fonts/glyphicons-halflings-regular.eot diff --git a/cabot/static/theme/fonts/glyphicons-halflings-regular.svg b/cabot3/static/theme/fonts/glyphicons-halflings-regular.svg similarity index 100% rename from cabot/static/theme/fonts/glyphicons-halflings-regular.svg rename to cabot3/static/theme/fonts/glyphicons-halflings-regular.svg diff --git a/cabot/static/theme/fonts/glyphicons-halflings-regular.ttf b/cabot3/static/theme/fonts/glyphicons-halflings-regular.ttf similarity index 100% rename from cabot/static/theme/fonts/glyphicons-halflings-regular.ttf rename to cabot3/static/theme/fonts/glyphicons-halflings-regular.ttf diff --git a/cabot/static/theme/fonts/glyphicons-halflings-regular.woff b/cabot3/static/theme/fonts/glyphicons-halflings-regular.woff similarity index 100% rename from cabot/static/theme/fonts/glyphicons-halflings-regular.woff rename to cabot3/static/theme/fonts/glyphicons-halflings-regular.woff diff --git a/cabot/static/theme/fonts/glyphicons-halflings-regular.woff2 b/cabot3/static/theme/fonts/glyphicons-halflings-regular.woff2 similarity index 100% rename from cabot/static/theme/fonts/glyphicons-halflings-regular.woff2 rename to cabot3/static/theme/fonts/glyphicons-halflings-regular.woff2 diff --git a/cabot/static/theme/img/animated-overlay.gif b/cabot3/static/theme/img/animated-overlay.gif similarity index 100% rename from cabot/static/theme/img/animated-overlay.gif rename to cabot3/static/theme/img/animated-overlay.gif diff --git a/cabot/static/theme/img/arrows-active.png b/cabot3/static/theme/img/arrows-active.png similarity index 100% rename from cabot/static/theme/img/arrows-active.png rename to cabot3/static/theme/img/arrows-active.png diff --git a/cabot/static/theme/img/arrows-normal.png b/cabot3/static/theme/img/arrows-normal.png similarity index 100% rename from cabot/static/theme/img/arrows-normal.png rename to cabot3/static/theme/img/arrows-normal.png diff --git a/cabot/static/theme/img/bg-input-focus.png b/cabot3/static/theme/img/bg-input-focus.png similarity index 100% rename from cabot/static/theme/img/bg-input-focus.png rename to cabot3/static/theme/img/bg-input-focus.png diff --git a/cabot/static/theme/img/bg-input.png b/cabot3/static/theme/img/bg-input.png similarity index 100% rename from cabot/static/theme/img/bg-input.png rename to cabot3/static/theme/img/bg-input.png diff --git a/cabot/static/theme/img/bg-login.jpg b/cabot3/static/theme/img/bg-login.jpg similarity index 100% rename from cabot/static/theme/img/bg-login.jpg rename to cabot3/static/theme/img/bg-login.jpg diff --git a/cabot/static/theme/img/bg.jpg b/cabot3/static/theme/img/bg.jpg similarity index 100% rename from cabot/static/theme/img/bg.jpg rename to cabot3/static/theme/img/bg.jpg diff --git a/cabot/static/theme/img/buttons.gif b/cabot3/static/theme/img/buttons.gif similarity index 100% rename from cabot/static/theme/img/buttons.gif rename to cabot3/static/theme/img/buttons.gif diff --git a/cabot/static/theme/img/calendar.gif b/cabot3/static/theme/img/calendar.gif similarity index 100% rename from cabot/static/theme/img/calendar.gif rename to cabot3/static/theme/img/calendar.gif diff --git a/cabot/static/theme/img/chat-left.png b/cabot3/static/theme/img/chat-left.png similarity index 100% rename from cabot/static/theme/img/chat-left.png rename to cabot3/static/theme/img/chat-left.png diff --git a/cabot/static/theme/img/chat-right.png b/cabot3/static/theme/img/chat-right.png similarity index 100% rename from cabot/static/theme/img/chat-right.png rename to cabot3/static/theme/img/chat-right.png diff --git a/cabot/static/theme/img/chosen-sprite.png b/cabot3/static/theme/img/chosen-sprite.png similarity index 100% rename from cabot/static/theme/img/chosen-sprite.png rename to cabot3/static/theme/img/chosen-sprite.png diff --git a/cabot/static/theme/img/close-button-white.png b/cabot3/static/theme/img/close-button-white.png similarity index 100% rename from cabot/static/theme/img/close-button-white.png rename to cabot3/static/theme/img/close-button-white.png diff --git a/cabot/static/theme/img/close-button.png b/cabot3/static/theme/img/close-button.png similarity index 100% rename from cabot/static/theme/img/close-button.png rename to cabot3/static/theme/img/close-button.png diff --git a/cabot/static/theme/img/crop.gif b/cabot3/static/theme/img/crop.gif similarity index 100% rename from cabot/static/theme/img/crop.gif rename to cabot3/static/theme/img/crop.gif diff --git a/cabot/static/theme/img/dbg.jpg b/cabot3/static/theme/img/dbg.jpg similarity index 100% rename from cabot/static/theme/img/dbg.jpg rename to cabot3/static/theme/img/dbg.jpg diff --git a/cabot/static/theme/img/dialogs.png b/cabot3/static/theme/img/dialogs.png similarity index 100% rename from cabot/static/theme/img/dialogs.png rename to cabot3/static/theme/img/dialogs.png diff --git a/cabot/static/theme/img/favicon.ico b/cabot3/static/theme/img/favicon.ico similarity index 100% rename from cabot/static/theme/img/favicon.ico rename to cabot3/static/theme/img/favicon.ico diff --git a/cabot/static/theme/img/glyphicons-halflings-red.png b/cabot3/static/theme/img/glyphicons-halflings-red.png similarity index 100% rename from cabot/static/theme/img/glyphicons-halflings-red.png rename to cabot3/static/theme/img/glyphicons-halflings-red.png diff --git a/cabot/static/theme/img/glyphicons-halflings-white.png b/cabot3/static/theme/img/glyphicons-halflings-white.png similarity index 100% rename from cabot/static/theme/img/glyphicons-halflings-white.png rename to cabot3/static/theme/img/glyphicons-halflings-white.png diff --git a/cabot/static/theme/img/glyphicons-halflings.png b/cabot3/static/theme/img/glyphicons-halflings.png similarity index 100% rename from cabot/static/theme/img/glyphicons-halflings.png rename to cabot3/static/theme/img/glyphicons-halflings.png diff --git a/cabot/static/theme/img/i_16_radio.png b/cabot3/static/theme/img/i_16_radio.png similarity index 100% rename from cabot/static/theme/img/i_16_radio.png rename to cabot3/static/theme/img/i_16_radio.png diff --git a/cabot/static/theme/img/icons-big.png b/cabot3/static/theme/img/icons-big.png similarity index 100% rename from cabot/static/theme/img/icons-big.png rename to cabot3/static/theme/img/icons-big.png diff --git a/cabot/static/theme/img/icons-small.png b/cabot3/static/theme/img/icons-small.png similarity index 100% rename from cabot/static/theme/img/icons-small.png rename to cabot3/static/theme/img/icons-small.png diff --git a/cabot/static/theme/img/logo.png b/cabot3/static/theme/img/logo.png similarity index 100% rename from cabot/static/theme/img/logo.png rename to cabot3/static/theme/img/logo.png diff --git a/cabot/static/theme/img/logo20.png b/cabot3/static/theme/img/logo20.png similarity index 100% rename from cabot/static/theme/img/logo20.png rename to cabot3/static/theme/img/logo20.png diff --git a/cabot/static/theme/img/progress.gif b/cabot3/static/theme/img/progress.gif similarity index 100% rename from cabot/static/theme/img/progress.gif rename to cabot3/static/theme/img/progress.gif diff --git a/cabot/static/theme/img/quicklook-bg.png b/cabot3/static/theme/img/quicklook-bg.png similarity index 100% rename from cabot/static/theme/img/quicklook-bg.png rename to cabot3/static/theme/img/quicklook-bg.png diff --git a/cabot/static/theme/img/quicklook-icons.png b/cabot3/static/theme/img/quicklook-icons.png similarity index 100% rename from cabot/static/theme/img/quicklook-icons.png rename to cabot3/static/theme/img/quicklook-icons.png diff --git a/cabot/static/theme/img/resize.png b/cabot3/static/theme/img/resize.png similarity index 100% rename from cabot/static/theme/img/resize.png rename to cabot3/static/theme/img/resize.png diff --git a/cabot/static/theme/img/spinner-mini.gif b/cabot3/static/theme/img/spinner-mini.gif similarity index 100% rename from cabot/static/theme/img/spinner-mini.gif rename to cabot3/static/theme/img/spinner-mini.gif diff --git a/cabot/static/theme/img/sprite.png b/cabot3/static/theme/img/sprite.png similarity index 100% rename from cabot/static/theme/img/sprite.png rename to cabot3/static/theme/img/sprite.png diff --git a/cabot/static/theme/img/toolbar.gif b/cabot3/static/theme/img/toolbar.gif similarity index 100% rename from cabot/static/theme/img/toolbar.gif rename to cabot3/static/theme/img/toolbar.gif diff --git a/cabot/static/theme/img/toolbar.png b/cabot3/static/theme/img/toolbar.png similarity index 100% rename from cabot/static/theme/img/toolbar.png rename to cabot3/static/theme/img/toolbar.png diff --git a/cabot/static/theme/img/ui-bg_flat_0_aaaaaa_40x100.png b/cabot3/static/theme/img/ui-bg_flat_0_aaaaaa_40x100.png similarity index 100% rename from cabot/static/theme/img/ui-bg_flat_0_aaaaaa_40x100.png rename to cabot3/static/theme/img/ui-bg_flat_0_aaaaaa_40x100.png diff --git a/cabot/static/theme/img/ui-bg_flat_75_ffffff_40x100.png b/cabot3/static/theme/img/ui-bg_flat_75_ffffff_40x100.png similarity index 100% rename from cabot/static/theme/img/ui-bg_flat_75_ffffff_40x100.png rename to cabot3/static/theme/img/ui-bg_flat_75_ffffff_40x100.png diff --git a/cabot/static/theme/img/ui-bg_glass_55_fbf9ee_1x400.png b/cabot3/static/theme/img/ui-bg_glass_55_fbf9ee_1x400.png similarity index 100% rename from cabot/static/theme/img/ui-bg_glass_55_fbf9ee_1x400.png rename to cabot3/static/theme/img/ui-bg_glass_55_fbf9ee_1x400.png diff --git a/cabot/static/theme/img/ui-bg_glass_65_ffffff_1x400.png b/cabot3/static/theme/img/ui-bg_glass_65_ffffff_1x400.png similarity index 100% rename from cabot/static/theme/img/ui-bg_glass_65_ffffff_1x400.png rename to cabot3/static/theme/img/ui-bg_glass_65_ffffff_1x400.png diff --git a/cabot/static/theme/img/ui-bg_glass_75_dadada_1x400.png b/cabot3/static/theme/img/ui-bg_glass_75_dadada_1x400.png similarity index 100% rename from cabot/static/theme/img/ui-bg_glass_75_dadada_1x400.png rename to cabot3/static/theme/img/ui-bg_glass_75_dadada_1x400.png diff --git a/cabot/static/theme/img/ui-bg_glass_75_e6e6e6_1x400.png b/cabot3/static/theme/img/ui-bg_glass_75_e6e6e6_1x400.png similarity index 100% rename from cabot/static/theme/img/ui-bg_glass_75_e6e6e6_1x400.png rename to cabot3/static/theme/img/ui-bg_glass_75_e6e6e6_1x400.png diff --git a/cabot/static/theme/img/ui-bg_glass_95_fef1ec_1x400.png b/cabot3/static/theme/img/ui-bg_glass_95_fef1ec_1x400.png similarity index 100% rename from cabot/static/theme/img/ui-bg_glass_95_fef1ec_1x400.png rename to cabot3/static/theme/img/ui-bg_glass_95_fef1ec_1x400.png diff --git a/cabot/static/theme/img/ui-bg_highlight-soft_75_cccccc_1x100.png b/cabot3/static/theme/img/ui-bg_highlight-soft_75_cccccc_1x100.png similarity index 100% rename from cabot/static/theme/img/ui-bg_highlight-soft_75_cccccc_1x100.png rename to cabot3/static/theme/img/ui-bg_highlight-soft_75_cccccc_1x100.png diff --git a/cabot/static/theme/img/ui-icons_222222_256x240.png b/cabot3/static/theme/img/ui-icons_222222_256x240.png similarity index 100% rename from cabot/static/theme/img/ui-icons_222222_256x240.png rename to cabot3/static/theme/img/ui-icons_222222_256x240.png diff --git a/cabot/static/theme/img/ui-icons_2e83ff_256x240.png b/cabot3/static/theme/img/ui-icons_2e83ff_256x240.png similarity index 100% rename from cabot/static/theme/img/ui-icons_2e83ff_256x240.png rename to cabot3/static/theme/img/ui-icons_2e83ff_256x240.png diff --git a/cabot/static/theme/img/ui-icons_454545_256x240.png b/cabot3/static/theme/img/ui-icons_454545_256x240.png similarity index 100% rename from cabot/static/theme/img/ui-icons_454545_256x240.png rename to cabot3/static/theme/img/ui-icons_454545_256x240.png diff --git a/cabot/static/theme/img/ui-icons_888888_256x240.png b/cabot3/static/theme/img/ui-icons_888888_256x240.png similarity index 100% rename from cabot/static/theme/img/ui-icons_888888_256x240.png rename to cabot3/static/theme/img/ui-icons_888888_256x240.png diff --git a/cabot/static/theme/img/ui-icons_cd0a0a_256x240.png b/cabot3/static/theme/img/ui-icons_cd0a0a_256x240.png similarity index 100% rename from cabot/static/theme/img/ui-icons_cd0a0a_256x240.png rename to cabot3/static/theme/img/ui-icons_cd0a0a_256x240.png diff --git a/cabot/static/theme/js/bootstrap.js b/cabot3/static/theme/js/bootstrap.js similarity index 100% rename from cabot/static/theme/js/bootstrap.js rename to cabot3/static/theme/js/bootstrap.js diff --git a/cabot/static/theme/js/chosen.jquery.js b/cabot3/static/theme/js/chosen.jquery.js similarity index 100% rename from cabot/static/theme/js/chosen.jquery.js rename to cabot3/static/theme/js/chosen.jquery.js diff --git a/cabot/static/theme/js/custom.js b/cabot3/static/theme/js/custom.js similarity index 100% rename from cabot/static/theme/js/custom.js rename to cabot3/static/theme/js/custom.js diff --git a/cabot/static/theme/js/jquery-ui.js b/cabot3/static/theme/js/jquery-ui.js similarity index 100% rename from cabot/static/theme/js/jquery-ui.js rename to cabot3/static/theme/js/jquery-ui.js diff --git a/cabot/static/theme/js/jquery.dataTables.bootstrap.min.js b/cabot3/static/theme/js/jquery.dataTables.bootstrap.min.js similarity index 100% rename from cabot/static/theme/js/jquery.dataTables.bootstrap.min.js rename to cabot3/static/theme/js/jquery.dataTables.bootstrap.min.js diff --git a/cabot/static/theme/js/jquery.dataTables.min.js b/cabot3/static/theme/js/jquery.dataTables.min.js similarity index 100% rename from cabot/static/theme/js/jquery.dataTables.min.js rename to cabot3/static/theme/js/jquery.dataTables.min.js diff --git a/cabot/static/theme/js/jquery.sparkline.min.js b/cabot3/static/theme/js/jquery.sparkline.min.js similarity index 100% rename from cabot/static/theme/js/jquery.sparkline.min.js rename to cabot3/static/theme/js/jquery.sparkline.min.js diff --git a/cabot/static/theme/js/jquery.ui.autocomplete.js b/cabot3/static/theme/js/jquery.ui.autocomplete.js similarity index 100% rename from cabot/static/theme/js/jquery.ui.autocomplete.js rename to cabot3/static/theme/js/jquery.ui.autocomplete.js diff --git a/cabot/static/theme/js/jquery.ui.core.js b/cabot3/static/theme/js/jquery.ui.core.js similarity index 100% rename from cabot/static/theme/js/jquery.ui.core.js rename to cabot3/static/theme/js/jquery.ui.core.js diff --git a/cabot/static/theme/js/jquery.ui.position.js b/cabot3/static/theme/js/jquery.ui.position.js similarity index 100% rename from cabot/static/theme/js/jquery.ui.position.js rename to cabot3/static/theme/js/jquery.ui.position.js diff --git a/cabot/templates/404.html b/cabot3/templates/404.html similarity index 100% rename from cabot/templates/404.html rename to cabot3/templates/404.html diff --git a/cabot/templates/500.html b/cabot3/templates/500.html similarity index 100% rename from cabot/templates/500.html rename to cabot3/templates/500.html diff --git a/cabot/templates/base.html b/cabot3/templates/base.html similarity index 100% rename from cabot/templates/base.html rename to cabot3/templates/base.html diff --git a/cabot/templates/base_public.html b/cabot3/templates/base_public.html similarity index 100% rename from cabot/templates/base_public.html rename to cabot3/templates/base_public.html diff --git a/cabot/templates/cabotapp/_base_form.html b/cabot3/templates/cabotapp/_base_form.html similarity index 100% rename from cabot/templates/cabotapp/_base_form.html rename to cabot3/templates/cabotapp/_base_form.html diff --git a/cabot/templates/cabotapp/_instance_list.html b/cabot3/templates/cabotapp/_instance_list.html similarity index 100% rename from cabot/templates/cabotapp/_instance_list.html rename to cabot3/templates/cabotapp/_instance_list.html diff --git a/cabot/templates/cabotapp/_service_list.html b/cabot3/templates/cabotapp/_service_list.html similarity index 100% rename from cabot/templates/cabotapp/_service_list.html rename to cabot3/templates/cabotapp/_service_list.html diff --git a/cabot/templates/cabotapp/_service_public_list.html b/cabot3/templates/cabotapp/_service_public_list.html similarity index 100% rename from cabot/templates/cabotapp/_service_public_list.html rename to cabot3/templates/cabotapp/_service_public_list.html diff --git a/cabot/templates/cabotapp/_statuscheck_list.html b/cabot3/templates/cabotapp/_statuscheck_list.html similarity index 100% rename from cabot/templates/cabotapp/_statuscheck_list.html rename to cabot3/templates/cabotapp/_statuscheck_list.html diff --git a/cabot/templates/cabotapp/about.html b/cabot3/templates/cabotapp/about.html similarity index 100% rename from cabot/templates/cabotapp/about.html rename to cabot3/templates/cabotapp/about.html diff --git a/cabot/templates/cabotapp/alertpluginuserdata_form.html b/cabot3/templates/cabotapp/alertpluginuserdata_form.html similarity index 100% rename from cabot/templates/cabotapp/alertpluginuserdata_form.html rename to cabot3/templates/cabotapp/alertpluginuserdata_form.html diff --git a/cabot/templates/cabotapp/instance_confirm_delete.html b/cabot3/templates/cabotapp/instance_confirm_delete.html similarity index 100% rename from cabot/templates/cabotapp/instance_confirm_delete.html rename to cabot3/templates/cabotapp/instance_confirm_delete.html diff --git a/cabot/templates/cabotapp/instance_detail.html b/cabot3/templates/cabotapp/instance_detail.html similarity index 100% rename from cabot/templates/cabotapp/instance_detail.html rename to cabot3/templates/cabotapp/instance_detail.html diff --git a/cabot/templates/cabotapp/instance_form.html b/cabot3/templates/cabotapp/instance_form.html similarity index 100% rename from cabot/templates/cabotapp/instance_form.html rename to cabot3/templates/cabotapp/instance_form.html diff --git a/cabot/templates/cabotapp/instance_list.html b/cabot3/templates/cabotapp/instance_list.html similarity index 100% rename from cabot/templates/cabotapp/instance_list.html rename to cabot3/templates/cabotapp/instance_list.html diff --git a/cabot/templates/cabotapp/plugin_settings_form.html b/cabot3/templates/cabotapp/plugin_settings_form.html similarity index 100% rename from cabot/templates/cabotapp/plugin_settings_form.html rename to cabot3/templates/cabotapp/plugin_settings_form.html diff --git a/cabot/templates/cabotapp/service_confirm_delete.html b/cabot3/templates/cabotapp/service_confirm_delete.html similarity index 100% rename from cabot/templates/cabotapp/service_confirm_delete.html rename to cabot3/templates/cabotapp/service_confirm_delete.html diff --git a/cabot/templates/cabotapp/service_detail.html b/cabot3/templates/cabotapp/service_detail.html similarity index 100% rename from cabot/templates/cabotapp/service_detail.html rename to cabot3/templates/cabotapp/service_detail.html diff --git a/cabot/templates/cabotapp/service_form.html b/cabot3/templates/cabotapp/service_form.html similarity index 100% rename from cabot/templates/cabotapp/service_form.html rename to cabot3/templates/cabotapp/service_form.html diff --git a/cabot/templates/cabotapp/service_list.html b/cabot3/templates/cabotapp/service_list.html similarity index 100% rename from cabot/templates/cabotapp/service_list.html rename to cabot3/templates/cabotapp/service_list.html diff --git a/cabot/templates/cabotapp/service_public_list.html b/cabot3/templates/cabotapp/service_public_list.html similarity index 100% rename from cabot/templates/cabotapp/service_public_list.html rename to cabot3/templates/cabotapp/service_public_list.html diff --git a/cabot/templates/cabotapp/setup.html b/cabot3/templates/cabotapp/setup.html similarity index 100% rename from cabot/templates/cabotapp/setup.html rename to cabot3/templates/cabotapp/setup.html diff --git a/cabot/templates/cabotapp/shift_list.html b/cabot3/templates/cabotapp/shift_list.html similarity index 100% rename from cabot/templates/cabotapp/shift_list.html rename to cabot3/templates/cabotapp/shift_list.html diff --git a/cabot/templates/cabotapp/statuscheck_confirm_delete.html b/cabot3/templates/cabotapp/statuscheck_confirm_delete.html similarity index 100% rename from cabot/templates/cabotapp/statuscheck_confirm_delete.html rename to cabot3/templates/cabotapp/statuscheck_confirm_delete.html diff --git a/cabot/templates/cabotapp/statuscheck_detail.html b/cabot3/templates/cabotapp/statuscheck_detail.html similarity index 100% rename from cabot/templates/cabotapp/statuscheck_detail.html rename to cabot3/templates/cabotapp/statuscheck_detail.html diff --git a/cabot/templates/cabotapp/statuscheck_form.html b/cabot3/templates/cabotapp/statuscheck_form.html similarity index 100% rename from cabot/templates/cabotapp/statuscheck_form.html rename to cabot3/templates/cabotapp/statuscheck_form.html diff --git a/cabot/templates/cabotapp/statuscheck_list.html b/cabot3/templates/cabotapp/statuscheck_list.html similarity index 100% rename from cabot/templates/cabotapp/statuscheck_list.html rename to cabot3/templates/cabotapp/statuscheck_list.html diff --git a/cabot/templates/cabotapp/statuscheck_report.html b/cabot3/templates/cabotapp/statuscheck_report.html similarity index 100% rename from cabot/templates/cabotapp/statuscheck_report.html rename to cabot3/templates/cabotapp/statuscheck_report.html diff --git a/cabot/templates/cabotapp/statuscheckresult_detail.html b/cabot3/templates/cabotapp/statuscheckresult_detail.html similarity index 100% rename from cabot/templates/cabotapp/statuscheckresult_detail.html rename to cabot3/templates/cabotapp/statuscheckresult_detail.html diff --git a/cabot/templates/cabotapp/subscriptions.html b/cabot3/templates/cabotapp/subscriptions.html similarity index 100% rename from cabot/templates/cabotapp/subscriptions.html rename to cabot3/templates/cabotapp/subscriptions.html diff --git a/cabot/templates/registration/login.html b/cabot3/templates/registration/login.html similarity index 100% rename from cabot/templates/registration/login.html rename to cabot3/templates/registration/login.html diff --git a/cabot/templates/registration/logout.html b/cabot3/templates/registration/logout.html similarity index 100% rename from cabot/templates/registration/logout.html rename to cabot3/templates/registration/logout.html diff --git a/cabot/templates/registration/social_auth.html b/cabot3/templates/registration/social_auth.html similarity index 100% rename from cabot/templates/registration/social_auth.html rename to cabot3/templates/registration/social_auth.html diff --git a/cabot/urls.py b/cabot3/urls.py similarity index 97% rename from cabot/urls.py rename to cabot3/urls.py index b7462895c..0366f831e 100644 --- a/cabot/urls.py +++ b/cabot3/urls.py @@ -2,22 +2,22 @@ from django.urls import path from django.conf import settings from requests.api import request -from cabot.cabotapp.views import ( +from cabot3.cabotapp.views import ( about, run_status_check, graphite_api_data, checks_run_recently, duplicate_instance, acknowledge_alert, remove_acknowledgement, StatusCheckDeleteView, StatusCheckListView, StatusCheckDetailView, StatusCheckResultDetailView, StatusCheckReportView, UserProfileUpdateAlert, PluginSettingsView, AlertTestView, AlertTestPluginView, SetupView, OnCallView) -from cabot.cabotapp.views import (InstanceListView, InstanceDetailView, +from cabot3.cabotapp.views import (InstanceListView, InstanceDetailView, InstanceUpdateView, InstanceCreateView, InstanceDeleteView, ServiceListView, ServicePublicListView, ServiceDetailView, ServiceUpdateView, ServiceCreateView, ServiceDeleteView, UserProfileUpdateView, ShiftListView, subscriptions) -from cabot.cabotapp.utils import cabot_needs_setup +from cabot3.cabotapp.utils import cabot_needs_setup -from cabot import rest_urls +from cabot3 import rest_urls from rest_framework.documentation import include_docs_urls from django.contrib import admin diff --git a/cabot/version.py b/cabot3/version.py similarity index 59% rename from cabot/version.py rename to cabot3/version.py index de6eebbc0..e550845b8 100644 --- a/cabot/version.py +++ b/cabot3/version.py @@ -1,5 +1,5 @@ try: import pkg_resources - version = pkg_resources.require("cabot")[0].version + version = pkg_resources.require("cabot3")[0].version except Exception(ImportError): version = 'unknown' diff --git a/cabot/wsgi.py b/cabot3/wsgi.py similarity index 59% rename from cabot/wsgi.py rename to cabot3/wsgi.py index 0b85c3489..78497226d 100644 --- a/cabot/wsgi.py +++ b/cabot3/wsgi.py @@ -1,6 +1,6 @@ import os -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'cabot.settings') +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'cabot3.settings') from django.core.wsgi import get_wsgi_application application = get_wsgi_application() diff --git a/manage.py b/manage.py index ede6b8f10..92fa585e5 100755 --- a/manage.py +++ b/manage.py @@ -7,7 +7,7 @@ if __name__ == "__main__": - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cabot.settings") + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cabot3.settings") from django.core.management import execute_from_command_line diff --git a/setup.cfg b/setup.cfg index e69de29bb..0a05b6117 100644 --- a/setup.cfg +++ b/setup.cfg @@ -0,0 +1,2 @@ +[metadata] + description-file = README.md \ No newline at end of file diff --git a/setup.py b/setup.py index f73cdb53d..a3b402dbb 100644 --- a/setup.py +++ b/setup.py @@ -1,13 +1,13 @@ from distutils.core import setup setup( - name = 'mypackage', - packages = ['mypackage'], # this must be the same as the name above + name = 'cabot3', + packages = ['cabot3'], # this must be the same as the name above version = '0.1', - description = 'my description', - author = 'Alejandro Esquiva', - author_email = 'alejandro@geekytheory.com', - url = 'https://github.com/{user_name}/{repo}', # use the URL to the github repo - download_url = 'https://github.com/{user_name}/{repo}/tarball/0.1', + description = 'Cabot system migrated to python 3.6', + author = 'Tomas Grossi', + author_email = 'tomas@senzil.com', + url = 'https://github.com/senzil/cabot', # use the URL to the github repo + download_url = 'https://github.com/senzil/cabot/tarball/0.1', keywords = ['testing', 'logging', 'example'], classifiers = [], ) From 23b14e75577c358e9f79bc146ef3e514e3016b28 Mon Sep 17 00:00:00 2001 From: Ladrusca Date: Mon, 23 Aug 2021 19:16:20 -0300 Subject: [PATCH 10/24] modificaciones menores --- Dockerfile | 8 ++++---- cabot3/.env _example | 4 ++-- docker-compose.yml | 13 ++++++------- docker-entrypoint.sh | 6 +++--- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/Dockerfile b/Dockerfile index c4286105e..07ed97784 100644 --- a/Dockerfile +++ b/Dockerfile @@ -49,10 +49,10 @@ FROM python:3.6-alpine AS runner-image RUN apk add --no-cache libpq \ mariadb-connector-c-dev -RUN adduser -S cabot + +USER root COPY --from=builder-image /home/cabot3/venv /home/cabot3/venv -USER cabot RUN mkdir /home/cabot3/code WORKDIR /home/cabot3/code @@ -72,7 +72,7 @@ ENV PATH="/home/cabot3/venv/bin:$PATH" # /dev/shm is mapped to shared memory and should be used for gunicorn heartbeat # this will improve performance and avoid random freezes -#CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"] +CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"] -ENTRYPOINT ["sh","docker-entrypoint.sh"] +#ENTRYPOINT ["sh","docker-entrypoint.sh"] diff --git a/cabot3/.env _example b/cabot3/.env _example index 46d4b3102..12f5dfa9f 100644 --- a/cabot3/.env _example +++ b/cabot3/.env _example @@ -20,8 +20,8 @@ PORT=8000 TIME_ZONE=America/Argentina/Buenos_Aires #################### CELERY CONFIG -CELERY_BROKER_URL=redis://redis:6379/1 -CELERY_RESULT_BACKEND=redis://redis:6379/1 +CELERY_BROKER_URL=redis://127.0.0.1:6379/1 +CELERY_RESULT_BACKEND=redis://127.0.0.1:6379/1 CELERY_BEAT_SCHEDULER=django_celery_beat.schedulers:DatabaseScheduler #################### DJANGO MAIL CONFIG diff --git a/docker-compose.yml b/docker-compose.yml index 60335d0b7..e2665ba3b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,7 +3,7 @@ services: db: image: mysql ports: - - '3306:3306' + - '3307:3307' environment: MYSQL_DATABASE: 'cabot' MYSQL_ROOT_PASSWORD: 'root' @@ -21,22 +21,21 @@ services: extends: file: docker-compose-base.yml service: base - command: sh -c "python manage.py migrate && python manage.py runserver 0.0.0.0:8000" + command: sh -c "sleep 30 && python manage.py migrate && python manage.py runserver 0.0.0.0:8000" ports: - "8000:8000" - links: - - redis + depends_on: - db - + worker-beat: extends: file: docker-compose-base.yml service: base - command: celery -A cabot worker --beat --scheduler django --loglevel=info + command: sh -c "sleep 60 && celery -A cabot3 worker --beat --scheduler django --loglevel=info" environment: - SKIP_INIT=1 - WAIT_FOR_MIGRATIONS=1 - links: + depends_on: - redis - db diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 8c63e1fd1..bf24da85c 100644 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -6,7 +6,7 @@ function wait_for_broker { for try in {1..60} ; do python -c "from kombu import Connection; x=Connection('$CELERY_BROKER_URL', timeout=1); x.connect()" && break echo "Waiting for celery broker to respond..." - sleep 1 + sleep 60 done } @@ -15,7 +15,7 @@ function wait_for_database { for try in {1..60} ; do python -c "from django.db import connection; connection.connect()" && break echo "Waiting for database to respond..." - sleep 1 + sleep 60 done } @@ -26,7 +26,7 @@ function wait_for_migrations { # showmigrations -p returns a checkbox list of migrations, empty checkboxes mean they haven't been run python manage.py showmigrations -p | grep "\[ \]" &> /dev/null || break echo "Waiting for database migrations to be run..." - sleep 1 + sleep 30 done } From 66984b6e46cfa33022a2423391e2eb3a28cd1eb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Gonz=C3=A1lez?= Date: Tue, 24 Aug 2021 17:19:07 -0300 Subject: [PATCH 11/24] add image deploy workflow --- .github/workflows/image_deploy.yaml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .github/workflows/image_deploy.yaml diff --git a/.github/workflows/image_deploy.yaml b/.github/workflows/image_deploy.yaml new file mode 100644 index 000000000..705fae73c --- /dev/null +++ b/.github/workflows/image_deploy.yaml @@ -0,0 +1,7 @@ +name: image-deploy +on: [push] +jobs: + build-and-push-image: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 From 007cab1ba7dd99489730470f5824132a189d6a99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Gonz=C3=A1lez?= Date: Tue, 24 Aug 2021 17:30:43 -0300 Subject: [PATCH 12/24] Create codeql-analysis.yml --- .github/workflows/codeql-analysis.yml | 71 +++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 000000000..c4cfb049c --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,71 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ master ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ master ] + schedule: + - cron: '35 7 * * 1' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'javascript', 'python' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] + # Learn more: + # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + # ℹī¸ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏ī¸ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 From 0f7b71340d3c9a307659d4930a9a4e8e1185ff48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Gonz=C3=A1lez?= Date: Tue, 24 Aug 2021 17:32:31 -0300 Subject: [PATCH 13/24] image deploy workflow --- .github/workflows/image_deploy.yaml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/.github/workflows/image_deploy.yaml b/.github/workflows/image_deploy.yaml index 705fae73c..b1fe36a69 100644 --- a/.github/workflows/image_deploy.yaml +++ b/.github/workflows/image_deploy.yaml @@ -1,7 +1,22 @@ name: image-deploy -on: [push] +on: + push: + branches: master jobs: build-and-push-image: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + - + name: Login to Docker Hub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - + name: Build and push + id: docker_build + uses: docker/build-push-action@v2 + with: + push: true + tags: senzil/cabot:latest From f63e47c01a962bb4474566a29540aac1ca020e57 Mon Sep 17 00:00:00 2001 From: Ladrusca Date: Tue, 24 Aug 2021 17:54:24 -0300 Subject: [PATCH 14/24] remove requirements-plugins --- .gitignore | 2 +- Dockerfile | 3 -- cabot3/.env _example | 1 + docker.env_example | 104 +++++++++++++++++++++++++++++---------- requirements-plugins.txt | 4 -- 5 files changed, 81 insertions(+), 33 deletions(-) delete mode 100644 requirements-plugins.txt diff --git a/.gitignore b/.gitignore index 5721c74c4..5db991a99 100644 --- a/.gitignore +++ b/.gitignore @@ -76,7 +76,7 @@ coverage.xml .hypothesis/ .pytest_cache/ cover/ - +.vscode # Translations *.mo *.pot diff --git a/Dockerfile b/Dockerfile index 07ed97784..c27027bed 100644 --- a/Dockerfile +++ b/Dockerfile @@ -40,9 +40,6 @@ WORKDIR /code COPY requirements.txt ./ RUN pip install --no-cache-dir -r requirements.txt -COPY requirements-plugins.txt ./ -RUN pip install --no-cache-dir -force-reinstall -r requirements-plugins.txt - ######################################################## FROM python:3.6-alpine AS runner-image diff --git a/cabot3/.env _example b/cabot3/.env _example index 12f5dfa9f..e225a0e89 100644 --- a/cabot3/.env _example +++ b/cabot3/.env _example @@ -37,6 +37,7 @@ EMAIL_PASSWORD=example SLACK_ALERT_CHANNEL=cabot SLACK_WEBHOOK_URL=https://discord.com/api/webhooks SLACK_ICON_URL=http://lorempixel.com/40/40/ +SLACK_INTERACTIVE_MESSAGE=True # Typical SMTP port 587 or 25 configuration (with no SSL/TLS) EMAIL_PORT=587 diff --git a/docker.env_example b/docker.env_example index 46d4b3102..362b2c3f6 100644 --- a/docker.env_example +++ b/docker.env_example @@ -1,20 +1,25 @@ -DEBUG=True -PROD=False +DEBUG=False +PROD=True +#################### SLACK CONFIG +SLACK_ALERT_CHANNEL= +SLACK_WEBHOOK_URL= +SLACK_ICON_URL=http://lorempixel.com/40/40/ +SLACK_INTERACTIVE_MESSAGE=True #################### DATABASE CONFIG #Check diferent options: https://github.com/kennethreitz/dj-database-url DATABASE_NAME=cabot -DATABASE_USER=root -DATABASE_PASSWORD=root +DATABASE_USER=cabot +DATABASE_PASSWORD=cabot DATABASE_HOST=db DATABASE_PORT=3306 -#################### PLUGINS - DON'T LEAVE SPACE BETWEEN THEM, ONLY COMMACABOT_PLUGINS=cabot_alert_slack,cabot_check_http,cabot_check_network,cabot_alert_email -CABOT_PLUGINS=cabot_alert_slack,cabot_check_http,cabot_check_network,cabot_alert_email +#################### PLUGINS - DON'T LEAVE SPACE BETWEEN THEM, ONLY COMMA +#CABOT_PLUGINS=cabot_alert_slack,cabot_check_http,cabot_check_network,cabot_alert_email #################### GENERAL CONFIG -DJANGO_SETTINGS_MODULE=cabot.settings +DJANGO_SETTINGS_MODULE=cabot3.settings LOG_FILE=/dev/null PORT=8000 TIME_ZONE=America/Argentina/Buenos_Aires @@ -24,43 +29,92 @@ CELERY_BROKER_URL=redis://redis:6379/1 CELERY_RESULT_BACKEND=redis://redis:6379/1 CELERY_BEAT_SCHEDULER=django_celery_beat.schedulers:DatabaseScheduler + + #################### DJANGO MAIL CONFIG -ADMIN_EMAIL=example@example.com -CABOT_FROM_EMAIL=example@example.com +ADMIN_EMAIL= +CABOT_FROM_EMAIL= -#################### EMAIL ALERT CONFIG -EMAIL_HOST=in-v3.example.com -EMAIL_USER=example -EMAIL_PASSWORD=example -#################### SLACK CONFIG -SLACK_ALERT_CHANNEL=cabot -SLACK_WEBHOOK_URL=https://discord.com/api/webhooks -SLACK_ICON_URL=http://lorempixel.com/40/40/ +#################### EMAIL ALERT CONFIG +EMAIL_HOST= +EMAIL_USER= +EMAIL_PASSWORD= # Typical SMTP port 587 or 25 configuration (with no SSL/TLS) EMAIL_PORT=587 EMAIL_USE_TLS=0 EMAIL_USE_SSL=0 + +# You shouldn't need to change anything above this line + +# Base path to include before generated URLs. If not defined, uses `/` +# URL_PREFIX=/ + +# Local time zone for this installation. Choices can be found here: +# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name + +# SMTP settings + + + + # URL of calendar to synchronise rota with CALENDAR_ICAL_URL=http://www.google.com/calendar/ical/example.ics # Django settings -DJANGO_SECRET_KEY=example +DJANGO_SECRET_KEY=2FL6ORhHwr5eX34pP9mMugnIOd3jzVuT45f7w430Mt5PnEwbcJgma0q8zUXNZ68A + +# Hostname of your Graphite server instance +GRAPHITE_API=http://graphite.example.com/ +GRAPHITE_USER=username +GRAPHITE_PASS=password + +# From parameter for the graphite request. If not defined, by default take -10 minutes +# GRAPHITE_FROM=-10minute # User-Agent string used for HTTP checks HTTP_USER_AGENT=Cabot +# Hipchat integration +HIPCHAT_ALERT_ROOM=room_name_or_id +HIPCHAT_API_KEY=your_hipchat_api_key + +# Jenkins integration +JENKINS_API=https://jenkins.example.com/ +JENKINS_USER=username +JENKINS_PASS=password + +# Twilio integration for SMS and telephone alerts +TWILIO_ACCOUNT_SID=your_account_sid +TWILIO_AUTH_TOKEN=your_auth_token +TWILIO_OUTGOING_NUMBER=+14155551234 + # Used for pointing links back in alerts etc. WWW_HTTP_HOST=localhost WWW_SCHEME=http -# Twilio integration for SMS and telephone alerts -#TWILIO_ACCOUNT_SID=your_account_sid -#TWILIO_AUTH_TOKEN=your_auth_token -#TWILIO_OUTGOING_NUMBER=+14155551234 +# Use for LDAP authentication +# AUTH_LDAP=true +# AUTH_LDAP_SERVER_URI=ldap://ldap.example.com +# AUTH_LDAP_BIND_DN="cn=Manager,dc=example,dc=com" +# AUTH_LDAP_BIND_PASSWORD="" +# AUTH_LDAP_USER_FILTER="(uid=%(user)s)" +# AUTH_LDAP_USER_SEARCH="ou=People,dc=example,dc=com" -# Hipchat integration -#HIPCHAT_ALERT_ROOM=room_name_or_id -#HIPCHAT_API_KEY=your_hipchat_api_key +# Use Github Organization for Authentication +# LOGIN_URL=/login/github-org/ +# AUTH_GITHUB_ORG=True +# AUTH_GITHUB_ORG_CLIENT_ID=2l34k5j43tb46l2kj234 +# AUTH_GITHUB_ORG_CLIENT_SECRET=23l4k5j43l6k546lk5n4kl64j2j3l5k4jjlkj2345 +# AUTH_GITHUB_ORG_NAME=myorganization + +# Use Github Enterprise Organization for Authentication +# LOGIN_URL=/login/github-enterprise-org/ +# GITHUB_ENTERPRISE_ORG_AUTH=True +# GITHUB_ENTERPRISE_ORG_URL=https://mygithubenterprise.com/ +# GITHUB_ENTERPRISE_ORG_API_URL=https://mygithubenterprise.com/api/v3/ +# GITHUB_ENTERPRISE_ORG_KEY=alskdjflkj5lk123j345l3 +# GITHUB_ENTERPRISE_ORG_SECRET=alskjdflkasjdflqkj5lkntrk13j45lk3451453245 +# GITHUB_ENTERPRISE_ORG_NAME=myorganization diff --git a/requirements-plugins.txt b/requirements-plugins.txt deleted file mode 100644 index 2482f8b62..000000000 --- a/requirements-plugins.txt +++ /dev/null @@ -1,4 +0,0 @@ -git+https://github.com/senzil/cabot-alert-email.git -git+https://github.com/senzil/cabot-check-http.git -git+https://github.com/senzil/cabot-alert-slack.git -git+https://github.com/senzil/cabot-check-network.git From 14537888cb128f81189f4f9ce735324da88ffa1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Gonz=C3=A1lez?= Date: Tue, 24 Aug 2021 18:04:21 -0300 Subject: [PATCH 15/24] added action for senzil branch --- .github/workflows/image_deploy.yaml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/.github/workflows/image_deploy.yaml b/.github/workflows/image_deploy.yaml index b1fe36a69..552665c9c 100644 --- a/.github/workflows/image_deploy.yaml +++ b/.github/workflows/image_deploy.yaml @@ -20,3 +20,24 @@ jobs: with: push: true tags: senzil/cabot:latest +on: + push: + branches: senzil +jobs: + build-and-push-image: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - + name: Login to Docker Hub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - + name: Build and push + id: docker_build + uses: docker/build-push-action@v2 + with: + push: true + tags: senzil/cabot:senzil From 0fe839e6f5154e23b9956eb2052ce02f86234d3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Gonz=C3=A1lez?= Date: Tue, 24 Aug 2021 18:08:06 -0300 Subject: [PATCH 16/24] added action for senzil branch --- .github/workflows/image_deploy.yaml | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/.github/workflows/image_deploy.yaml b/.github/workflows/image_deploy.yaml index 552665c9c..6dd97faf3 100644 --- a/.github/workflows/image_deploy.yaml +++ b/.github/workflows/image_deploy.yaml @@ -19,25 +19,4 @@ jobs: uses: docker/build-push-action@v2 with: push: true - tags: senzil/cabot:latest -on: - push: - branches: senzil -jobs: - build-and-push-image: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - - name: Login to Docker Hub - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Build and push - id: docker_build - uses: docker/build-push-action@v2 - with: - push: true - tags: senzil/cabot:senzil + tags: senzil/cabot:latest \ No newline at end of file From ab0889ae517407185a676125a88240115019afaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Gonz=C3=A1lez?= Date: Wed, 25 Aug 2021 08:06:40 -0300 Subject: [PATCH 17/24] Added git to runner image to install pip package from repositories --- Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index c27027bed..445107d37 100644 --- a/Dockerfile +++ b/Dockerfile @@ -44,7 +44,8 @@ RUN pip install --no-cache-dir -r requirements.txt FROM python:3.6-alpine AS runner-image RUN apk add --no-cache libpq \ - mariadb-connector-c-dev + mariadb-connector-c-dev \ + git USER root From 059b315c0e25f82428fddb5fae70aba2eae2be24 Mon Sep 17 00:00:00 2001 From: Ladrusca Date: Wed, 25 Aug 2021 15:44:01 -0300 Subject: [PATCH 18/24] added gunicorn to dockerfile --- Dockerfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 445107d37..4842377aa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -45,8 +45,8 @@ FROM python:3.6-alpine AS runner-image RUN apk add --no-cache libpq \ mariadb-connector-c-dev \ - git - + git \ + && pip install --no-cache-dir gunicorn USER root COPY --from=builder-image /home/cabot3/venv /home/cabot3/venv @@ -67,6 +67,7 @@ ENV PYTHONUNBUFFERED=1 ENV VIRTUAL_ENV=/home/cabot3/venv ENV PATH="/home/cabot3/venv/bin:$PATH" + # /dev/shm is mapped to shared memory and should be used for gunicorn heartbeat # this will improve performance and avoid random freezes From a498ef9c062e8b16ff4bbf500485ede3a9eb291a Mon Sep 17 00:00:00 2001 From: Ladrusca Date: Wed, 25 Aug 2021 16:34:31 -0300 Subject: [PATCH 19/24] changed gunicorn installation to first image docker --- Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 4842377aa..0e9ee7c7b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -38,15 +38,15 @@ RUN mkdir /code WORKDIR /code COPY requirements.txt ./ -RUN pip install --no-cache-dir -r requirements.txt +RUN pip install --no-cache-dir -r requirements.txt \ + && pip install --no-cache-dir gunicorn ######################################################## FROM python:3.6-alpine AS runner-image RUN apk add --no-cache libpq \ mariadb-connector-c-dev \ - git \ - && pip install --no-cache-dir gunicorn + git USER root COPY --from=builder-image /home/cabot3/venv /home/cabot3/venv From 76ad6b4a915a92ce266231c9b633f0f7a3712da4 Mon Sep 17 00:00:00 2001 From: Ladrusca Date: Thu, 26 Aug 2021 10:42:29 -0300 Subject: [PATCH 20/24] added whitenoise for static files on prod --- Dockerfile | 2 +- cabot3/settings.py | 4 ++-- requirements.txt | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0e9ee7c7b..caf8189fd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -39,7 +39,7 @@ WORKDIR /code COPY requirements.txt ./ RUN pip install --no-cache-dir -r requirements.txt \ - && pip install --no-cache-dir gunicorn + && pip install --no-cache-dir gunicorn ######################################################## FROM python:3.6-alpine AS runner-image diff --git a/cabot3/settings.py b/cabot3/settings.py index e42c7c709..5b082c6d6 100644 --- a/cabot3/settings.py +++ b/cabot3/settings.py @@ -95,8 +95,7 @@ # Additional locations of static files STATICFILES_DIRS = [os.path.join(PROJECT_ROOT, 'static')] -if not DEBUG: - STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' +STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' # List of finder classes that know how to find static files in # various locations. @@ -142,6 +141,7 @@ 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', + 'whitenoise.middleware.WhiteNoiseMiddleware', ) ROOT_URLCONF = 'cabot3.urls' diff --git a/requirements.txt b/requirements.txt index 7f8489712..d61ecdcae 100644 --- a/requirements.txt +++ b/requirements.txt @@ -54,3 +54,4 @@ urllib3==1.26.6 vine==5.0.0 wcwidth==0.2.5 zipp==3.5.0 +whitenoise==5.3.0 \ No newline at end of file From a274a532ba7c67440309d1632228833d95d3ef30 Mon Sep 17 00:00:00 2001 From: Ladrusca Date: Thu, 26 Aug 2021 12:37:04 -0300 Subject: [PATCH 21/24] correct whitenoise configuration and fixed bug in debug and prod settings --- .gitignore | 2 +- cabot3/.env _example | 2 +- cabot3/settings.py | 13 ++++++------- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index 5db991a99..4d9c6ecd5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,7 @@ dev.db venv/* backups/* -cabot3/.collectstatic/ +cabot3/staticfiles/ node_modules/* .python-eggs/* cabot.egg-info diff --git a/cabot3/.env _example b/cabot3/.env _example index e225a0e89..350500802 100644 --- a/cabot3/.env _example +++ b/cabot3/.env _example @@ -1,4 +1,4 @@ -DEBUG=True +DEBUG=False PROD=False #################### DATABASE CONFIG diff --git a/cabot3/settings.py b/cabot3/settings.py index 5b082c6d6..275454291 100644 --- a/cabot3/settings.py +++ b/cabot3/settings.py @@ -11,10 +11,10 @@ settings_dir = os.path.dirname(__file__) PROJECT_ROOT = os.path.abspath(settings_dir) - -DEBUG=os.environ.get('DEBUG', False) -PROD=os.environ.get('PROD', False) +DEBUG=force_bool(os.environ.get('DEBUG', False)) + +PROD=force_bool(os.environ.get('PROD', True)) ADMINS = ( @@ -83,7 +83,7 @@ # Don't put anything in this directory yourself; store your static files # in apps' "static/" subdirectories and in STATICFILES_DIRS. # Example: "/home/media/media.lawrence.com/static/" -STATIC_ROOT = os.path.join(PROJECT_ROOT, '.collectstatic/') +STATIC_ROOT = os.path.join(PROJECT_ROOT, 'staticfiles') COMPRESS_ROOT = STATIC_ROOT @@ -132,16 +132,14 @@ }] MIDDLEWARE = ( - - 'django.middleware.security.SecurityMiddleware', + 'whitenoise.middleware.WhiteNoiseMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', - 'whitenoise.middleware.WhiteNoiseMiddleware', ) ROOT_URLCONF = 'cabot3.urls' @@ -151,6 +149,7 @@ 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', + 'whitenoise.runserver_nostatic', 'django.contrib.staticfiles', # Uncomment the next line to enable admin documentation: # 'django.contrib.admindocs', From d90be5322e1488c8f14083f42043f713cb86ed77 Mon Sep 17 00:00:00 2001 From: Ladrusca Date: Thu, 26 Aug 2021 15:50:26 -0300 Subject: [PATCH 22/24] added entrypoint to dockerfile and changed force_bool method --- Dockerfile | 4 ++-- cabot3/settings_utils.py | 5 +---- docker-compose.yml | 6 +++--- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/Dockerfile b/Dockerfile index caf8189fd..f3fb4a009 100644 --- a/Dockerfile +++ b/Dockerfile @@ -71,7 +71,7 @@ ENV PATH="/home/cabot3/venv/bin:$PATH" # /dev/shm is mapped to shared memory and should be used for gunicorn heartbeat # this will improve performance and avoid random freezes -CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"] +#CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"] -#ENTRYPOINT ["sh","docker-entrypoint.sh"] +ENTRYPOINT ["sh","docker-entrypoint.sh"] diff --git a/cabot3/settings_utils.py b/cabot3/settings_utils.py index 642cc853d..0f2e418f7 100644 --- a/cabot3/settings_utils.py +++ b/cabot3/settings_utils.py @@ -3,10 +3,7 @@ def force_bool(val): - if val == True or val == False: - return strtobool(str(val)) - else: - return False + return strtobool(str(val)) def environ_get_list(names, default=None): diff --git a/docker-compose.yml b/docker-compose.yml index e2665ba3b..52beb9987 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ version: '3' services: db: - image: mysql + image: mysql:5 ports: - '3307:3307' environment: @@ -21,7 +21,7 @@ services: extends: file: docker-compose-base.yml service: base - command: sh -c "sleep 30 && python manage.py migrate && python manage.py runserver 0.0.0.0:8000" + command: sh -c "python manage.py migrate && python manage.py runserver 0.0.0.0:8000" ports: - "8000:8000" depends_on: @@ -31,7 +31,7 @@ services: extends: file: docker-compose-base.yml service: base - command: sh -c "sleep 60 && celery -A cabot3 worker --beat --scheduler django --loglevel=info" + command: sh -c "celery -A cabot3 worker --beat --scheduler django --loglevel=info" environment: - SKIP_INIT=1 - WAIT_FOR_MIGRATIONS=1 From 7ff2e86f2ad04c2bea5195c2b22c959b5d726e21 Mon Sep 17 00:00:00 2001 From: Tomas Date: Thu, 26 Aug 2021 15:52:41 -0300 Subject: [PATCH 23/24] Update .env _example --- cabot3/.env _example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cabot3/.env _example b/cabot3/.env _example index 350500802..b333ebdac 100644 --- a/cabot3/.env _example +++ b/cabot3/.env _example @@ -14,7 +14,7 @@ DATABASE_PORT=3306 CABOT_PLUGINS=cabot_alert_slack,cabot_check_http,cabot_check_network,cabot_alert_email #################### GENERAL CONFIG -DJANGO_SETTINGS_MODULE=cabot.settings +DJANGO_SETTINGS_MODULE=cabot3.settings LOG_FILE=/dev/null PORT=8000 TIME_ZONE=America/Argentina/Buenos_Aires From 9a890aeac5ee324e8d3b2741113c4a18ed4d23a2 Mon Sep 17 00:00:00 2001 From: Ladrusca Date: Mon, 30 Aug 2021 15:29:07 -0300 Subject: [PATCH 24/24] added social django auth requirement --- requirements.txt | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index d61ecdcae..e7023848e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,10 @@ amqp==5.0.6 asgiref==3.4.1 billiard==3.6.4.0 -cabot-alert-slack==0.8.3 cached-property==1.5.2 celery==5.1.2 certifi==2021.5.30 +cffi==1.14.6 chardet==4.0.0 click==7.1.2 click-didyoumean==0.0.3 @@ -12,6 +12,8 @@ click-plugins==1.1.1 click-repl==0.2.0 coreapi==2.3.3 coreschema==0.0.4 +cryptography==3.4.8 +defusedxml==0.7.1 dj-database-url==0.5.0 Django==3.2.5 django-appconf==1.0.4 @@ -33,25 +35,32 @@ Jinja2==3.0.1 kombu==5.1.0 MarkupSafe==2.0.1 mysqlclient==2.0.3 +oauthlib==3.1.1 postgres==3.0.0 prompt-toolkit==3.0.19 psycopg2==2.9.1 psycopg2-binary==2.9.1 psycopg2-pool==1.1 +pycparser==2.20 +PyJWT==2.1.0 python-crontab==2.5.1 python-dateutil==2.8.2 python-dotenv==0.19.0 +python3-openid==3.2.0 pytz==2021.1 rcssmin==1.0.6 redis==3.5.3 requests==2.25.1 +requests-oauthlib==1.3.0 rjsmin==1.1.0 six==1.16.0 +social-auth-app-django==5.0.0 +social-auth-core==4.1.0 sqlparse==0.4.1 typing-extensions==3.10.0.0 uritemplate==3.0.1 urllib3==1.26.6 vine==5.0.0 wcwidth==0.2.5 +whitenoise==5.3.0 zipp==3.5.0 -whitenoise==5.3.0 \ No newline at end of file