diff options
author | Egor Yurtaev <yurtaev.egor@gmail.com> | 2015-07-29 16:47:50 +0600 |
---|---|---|
committer | Egor Yurtaev <yurtaev.egor@gmail.com> | 2015-07-29 16:48:30 +0600 |
commit | 9c809d2df43229db41bc1fc3d6d35e5a43917a8b (patch) | |
tree | 44d9ef655f963de402db9e7e0e45797122a462f8 | |
parent | c202d3ca85461fad889e5c05741f3febccb5de6e (diff) | |
download | omaha-server-9c809d2df43229db41bc1fc3d6d35e5a43917a8b.zip omaha-server-9c809d2df43229db41bc1fc3d6d35e5a43917a8b.tar.gz omaha-server-9c809d2df43229db41bc1fc3d6d35e5a43917a8b.tar.bz2 |
refactoring: public/private configs
26 files changed, 377 insertions, 82 deletions
diff --git a/.dockerignore b/.dockerignore index 6871028..b8e3656 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,6 +1,8 @@ .git .dockerignore +deploy/ + ### Python ### # Byte-compiled / optimized / DLL files @@ -30,6 +30,13 @@ RUN cd /usr/src/s3fs-fuse-1.78 && ./autogen.sh && ./configure --prefix=/usr && m RUN mkdir /srv/omaha_s3 +RUN mkdir $omaha +WORKDIR ${omaha} + +ADD ./requirements.txt $omaha/requirements.txt +RUN pip install paver --use-mirrors +RUN pip install -r requirements.txt --use-mirrors + ADD . $omaha # setup all the configfiles @@ -39,10 +46,5 @@ RUN ln -s /srv/omaha/conf/nginx.conf /etc/nginx/ RUN ln -s /srv/omaha/conf/nginx-app.conf /etc/nginx/sites-enabled/ RUN ln -s /srv/omaha/conf/supervisord.conf /etc/supervisor/conf.d/ -WORKDIR ${omaha} - -RUN pip install paver --use-mirrors -RUN pip install -r requirements.txt --use-mirrors - EXPOSE 80 CMD ["paver", "docker_run"] diff --git a/conf/supervisord.conf b/conf/supervisord.conf index d7c4d51..bbddf46 100644 --- a/conf/supervisord.conf +++ b/conf/supervisord.conf @@ -3,9 +3,13 @@ nodaemon=true [program:nginx-app] command = /usr/sbin/nginx +autostart=true +autorestart=true [program:omaha] command=uwsgi --ini /srv/omaha/conf/uwsgi.ini +autostart=true +autorestart=true [program:celery] command=celery worker -A omaha_server --loglevel=INFO @@ -16,4 +20,10 @@ autostart=true autorestart=true startsecs=10 stopwaitsecs = 600 -killasgroup=true
\ No newline at end of file +killasgroup=true + + +[program:s3fs] +command=/usr/bin/s3fs %(ENV_AWS_STORAGE_BUCKET_NAME)s /srv/omaha_s3 -ouse_cache=/tmp -oiam_role=%(ENV_AWS_ROLE)s +autostart=true +autorestart=true
\ No newline at end of file diff --git a/deploy/ebs.config.template b/deploy/ebs.config.template index e7066d8..7deba7d 100644 --- a/deploy/ebs.config.template +++ b/deploy/ebs.config.template @@ -28,15 +28,15 @@ app: all_environments: solution_stack_name: {{ app.solution_stack_name }} - #tier_name: 'WebServer' - #tier_type: 'Standard' - #tier_version: '1.0' option_settings: 'aws:autoscaling:launchconfiguration': InstanceType: {{ app.InstanceType }} {% set security = ','.join(app.security_groups) -%} SecurityGroups: {{ security }} + {% if app.profile -%} + IamInstanceProfile: {{ app.profile }} + {% endif -%} EC2KeyName: {{ app.key_name }} 'aws:autoscaling:asg': @@ -54,10 +54,6 @@ app: 'aws:elasticbeanstalk:application': Application Healthcheck URL: {{ app.healthcheck_url }} - 'aws:elasticbeanstalk:application:environment': - AWS_ACCESS_KEY_ID: {{ deploy.aws_access_key }} - AWS_SECRET_KEY: {{ deploy.aws_secret_key }} - archive: files: - .ebextensions/01_nginx.config: @@ -82,15 +78,25 @@ app: - Dockerrun.aws.json environments: - {% for env_name in app.environments.keys() -%} + {% for env_name in app.environments.keys() %} {{ env_name }}: cname_prefix: {{ env_name }} {% set env = app.environments[env_name] -%} - {% if env.environment -%} option_settings: + {% if env.environment -%} 'aws:elasticbeanstalk:application:environment': - {% for key, value in app.environments[env_name].environment.iteritems() -%} + HOST_NAME: {{ env_name }}.elasticbeanstalk.com + {% for key, value in env.environment.iteritems() -%} {{ key }}: {{ value }} {% endfor -%} {% endif -%} - {% endfor -%} + + {% if env.option_settings %} + {% for key, value in env.option_settings.iteritems() -%} + '{{ key }}': + {% for k, v in value.iteritems() -%} + '{{ k }}': {{ v }} + {% endfor -%} + {% endfor -%} + {% endif -%} + {% endfor %} diff --git a/deploy/main.py b/deploy/main.py index c2677eb..3ef2a1c 100755 --- a/deploy/main.py +++ b/deploy/main.py @@ -34,7 +34,7 @@ DEFAULT_SETTINGS = dict( solution_stack_name='64bit Amazon Linux 2015.03 v1.4.3 running Docker 1.6.2', InstanceType='t2.small', autoscaling=dict(min=1, max=10), - healthcheck_url='/admin/login/', + healthcheck_url='/healthcheck/status/', ), environment=dict( DJANGO_SETTINGS_MODULE='omaha_server.settings_dev', @@ -48,11 +48,15 @@ def get_settings(): with open(SETTINGS_PATH, 'r') as f: settings = yaml.load(f) - settings['app'].update(DEFAULT_SETTINGS['app']) + app_settings = DEFAULT_SETTINGS['app'].copy() + app_settings.update(settings['app']) + settings['app'] = app_settings environments = settings['app']['environments'] for env in environments.keys(): - environments[env]['environment'].update(DEFAULT_SETTINGS['environment']) + environment = DEFAULT_SETTINGS['environment'].copy() + environment.update(environments[env]['environment']) + environments[env]['environment'] = environment return settings diff --git a/deploy/playbook/omaha-server.yml b/deploy/playbook/omaha-server.yml index bee52f2..0ee80dd 100644 --- a/deploy/playbook/omaha-server.yml +++ b/deploy/playbook/omaha-server.yml @@ -65,9 +65,9 @@ module: iam_policy iam_name: omaha-server-s3-readonly iam_type: role - policy_name: s3-readonly + policy_name: s3-private state: present - policy_document: policies/s3_readonly.json + policy_document: policies/s3_private.json - name: create S3 bucket diff --git a/deploy/playbook/policies/s3_private.json b/deploy/playbook/policies/s3_private.json new file mode 100644 index 0000000..1863ace --- /dev/null +++ b/deploy/playbook/policies/s3_private.json @@ -0,0 +1,14 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "Stmt1437040026987", + "Action": "s3:*", + "Effect": "Allow", + "Resource": [ + "arn:aws:s3:::omaha-server", + "arn:aws:s3:::omaha-server/*" + ] + } + ] +} diff --git a/deploy/playbook/policies/s3_public.json b/deploy/playbook/policies/s3_public.json new file mode 100644 index 0000000..2c9d1db --- /dev/null +++ b/deploy/playbook/policies/s3_public.json @@ -0,0 +1,46 @@ +{ + "Version": "2012-10-17", + "Statement": [{ + "Action": [ + "s3:ListBucket" + ], + "Effect": "Allow", + "Resource": [ + "arn:aws:s3:::omaha-server-pp" + ] + }, { + "Action": [ + "s3:GetObject" + ], + "Effect": "Allow", + "Resource": [ + "arn:aws:s3:::omaha-server-pp/build/*" + ] + }, { + "Action": [ + "s3:GetObject" + ], + "Effect": "Allow", + "Resource": "arn:aws:s3:::omaha-server-pp/sparkle/*" + }, { + "Action": [ + "s3:GetObject", + "s3:PutObject" + ], + "Effect": "Allow", + "Resource": "arn:aws:s3:::omaha-server-pp/minidump_archive/*" + }, { + "Action": [ + "s3:GetObject", + "s3:PutObject" + ], + "Effect": "Allow", + "Resource": "arn:aws:s3:::omaha-server-pp/minidump/*" + }, { + "Action": [ + "s3:GetObject" + ], + "Effect": "Allow", + "Resource": "arn:aws:s3:::omaha-server-pp/symbols/*" + }] +} diff --git a/deploy/playbook/policies/s3_readonly.json b/deploy/playbook/policies/s3_readonly.json deleted file mode 100644 index 6a725b6..0000000 --- a/deploy/playbook/policies/s3_readonly.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": [ - "s3:Get*", - "s3:List*" - ], - "Resource": "*" - } - ] -} diff --git a/deploy/settings.yml.example b/deploy/settings.yml.example index e405031..0f9270d 100644 --- a/deploy/settings.yml.example +++ b/deploy/settings.yml.example @@ -10,18 +10,40 @@ app: security_groups: - omaha-server - - omaha-server-public key_name: omaha_server + profile: omaha-private environments: - omaha-server-dev: + omaha-server-private: environment: + OMAHA_SERVER_PRIVATE: true SECRET_KEY: ********** DB_HOST: postgres.example.com DB_USER: omaha DB_NAME: omaha - DB_PASSWORD: omaha + DB_PASSWORD: ********** AWS_STORAGE_BUCKET_NAME: omaha-server RAVEN_DNS: http://b3615b99118949dbae3c7d06e93fa74c:b8f1c35d08ef4bcaa6810b4d4cdd6fc0@sentry.example.com/2 RAVEN_DSN_STACKTRACE: http://637c17c832f44663b381916d4e0cb34d:9df83034cdfb400f9ce7d47ae4a0cc0b@sentry.example.com/5 REDIS_HOST: redis.example.com + DB_PUBLIC_USER: omaha_public + DB_PUBLIC_PASSWORD: omaha_public_password + AWS_ROLE: omaha-private + + omaha-server-public: + option_settings: + 'aws:autoscaling:launchconfiguration': + IamInstanceProfile: omaha-public + environment: + OMAHA_SERVER_PRIVATE: false + SECRET_KEY: ********** + DB_HOST: postgres.example.com + DB_USER: omaha_public + DB_NAME: omaha + DB_PASSWORD: omaha_public_password + AWS_STORAGE_BUCKET_NAME: omaha-server + RAVEN_DNS: http://b3615b99118949dbae3c7d06e93fa74c:b8f1c35d08ef4bcaa6810b4d4cdd6fc0@sentry.example.com/2 + RAVEN_DSN_STACKTRACE: http://637c17c832f44663b381916d4e0cb34d:9df83034cdfb400f9ce7d47ae4a0cc0b@sentry.example.com/5 + REDIS_HOST: redis.example.com + AWS_ROLE: omaha-public + DJANGO_SETTINGS_MODULE: omaha_server.settings_prod diff --git a/omaha_server/healthcheck/__init__.py b/omaha_server/healthcheck/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/omaha_server/healthcheck/__init__.py diff --git a/omaha_server/healthcheck/migrations/__init__.py b/omaha_server/healthcheck/migrations/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/omaha_server/healthcheck/migrations/__init__.py diff --git a/omaha_server/healthcheck/tests/__init__.py b/omaha_server/healthcheck/tests/__init__.py new file mode 100644 index 0000000..b727357 --- /dev/null +++ b/omaha_server/healthcheck/tests/__init__.py @@ -0,0 +1 @@ +# coding: utf8 diff --git a/omaha_server/healthcheck/tests/test_views.py b/omaha_server/healthcheck/tests/test_views.py new file mode 100644 index 0000000..0443db7 --- /dev/null +++ b/omaha_server/healthcheck/tests/test_views.py @@ -0,0 +1,37 @@ +# coding: utf8 + +""" +This software is licensed under the Apache 2 license, quoted below. + +Copyright 2014 Crystalnix Limited + +Licensed under the Apache License, Version 2.0 (the "License"); you may not +use this file except in compliance with the License. You may obtain a copy of +the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +License for the specific language governing permissions and limitations under +the License. +""" + +from django.core.urlresolvers import reverse +from django.conf import settings + +from rest_framework import status +from rest_framework.test import APITestCase + + +class StatusTests(APITestCase): + def test_view(self): + url = reverse('status') + data = dict( + status='ok', + version=settings.APP_VERSION, + ) + response = self.client.get(url) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.data, data) diff --git a/omaha_server/healthcheck/urls.py b/omaha_server/healthcheck/urls.py new file mode 100644 index 0000000..0d826eb --- /dev/null +++ b/omaha_server/healthcheck/urls.py @@ -0,0 +1,27 @@ +# coding: utf8 + +""" +This software is licensed under the Apache 2 license, quoted below. + +Copyright 2014 Crystalnix Limited + +Licensed under the Apache License, Version 2.0 (the "License"); you may not +use this file except in compliance with the License. You may obtain a copy of +the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +License for the specific language governing permissions and limitations under +the License. +""" + +from django.conf.urls import url + +from views import status + +urlpatterns = [ + url(r'^status/$', status, name='status'), +] diff --git a/omaha_server/healthcheck/views.py b/omaha_server/healthcheck/views.py new file mode 100644 index 0000000..5d0f9d1 --- /dev/null +++ b/omaha_server/healthcheck/views.py @@ -0,0 +1,36 @@ +# coding: utf8 + +""" +This software is licensed under the Apache 2 license, quoted below. + +Copyright 2014 Crystalnix Limited + +Licensed under the Apache License, Version 2.0 (the "License"); you may not +use this file except in compliance with the License. You may obtain a copy of +the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +License for the specific language governing permissions and limitations under +the License. +""" + +from django.conf import settings + +from rest_framework.decorators import api_view, permission_classes, renderer_classes +from rest_framework.response import Response +from rest_framework.permissions import AllowAny +from rest_framework.renderers import JSONRenderer + + +@api_view(['GET']) +@permission_classes((AllowAny,)) +@renderer_classes((JSONRenderer,)) +def status(request): + return Response(dict( + status='ok', + version=getattr(settings, 'APP_VERSION') + )) diff --git a/omaha_server/manage.py b/omaha_server/manage.py index 2ea4a4b..3cbff40 100755 --- a/omaha_server/manage.py +++ b/omaha_server/manage.py @@ -4,6 +4,8 @@ import sys if __name__ == "__main__": settings = "omaha_server.settings_test" if 'test' in sys.argv else 'omaha_server.settings' + if 'test' in sys.argv: + os.environ['OMAHA_SERVER_PRIVATE'] = 'True' os.environ.setdefault("DJANGO_SETTINGS_MODULE", settings) from django.core.management import execute_from_command_line diff --git a/omaha_server/omaha/models.py b/omaha_server/omaha/models.py index 56adc94..2172187 100644 --- a/omaha_server/omaha/models.py +++ b/omaha_server/omaha/models.py @@ -38,6 +38,7 @@ from django_extensions.db.fields import ( ) from jsonfield import JSONField from versionfield import VersionField +from furl import furl __all__ = ['Application', 'Channel', 'Platform', 'Version', @@ -127,11 +128,13 @@ class Version(BaseModel): @property def file_package_name(self): - return os.path.basename(self.file_absolute_url) + url = furl(self.file_absolute_url) + return os.path.basename(url.pathstr) @property def file_url(self): - return '%s/' % os.path.dirname(self.file_absolute_url) + url = furl(self.file_absolute_url) + return '%s://%s%s/' % (url.scheme, url.host, os.path.dirname(url.pathstr)) EVENT_DICT_CHOICES = dict( diff --git a/omaha_server/omaha/tests/test_models.py b/omaha_server/omaha/tests/test_models.py index ebdb4a6..5d94b48 100644 --- a/omaha_server/omaha/tests/test_models.py +++ b/omaha_server/omaha/tests/test_models.py @@ -74,6 +74,14 @@ class VersionModelTest(test.TestCase): 'http://cache.pack.google.com/edgedl/chrome/install/782.112/chrome_installer.exe') self.assertEqual(version.file_package_name, 'chrome_installer.exe') self.assertEqual(version.file_url, + u'http://cache.pack.google.com/edgedl/chrome/install/782.112/') + + @temporary_media_root(MEDIA_URL='http://cache.pack.google.com/edgedl/chrome/install/782.112/') + @patch('omaha.models.version_upload_to', lambda o, f: f) + def test_property_s3_meta_data(self): + version = VersionFactory.create(file=SimpleUploadedFile('./chrome_installer.exe', '')) + self.assertEqual(version.file_package_name, 'chrome_installer.exe') + self.assertEqual(version.file_url, 'http://cache.pack.google.com/edgedl/chrome/install/782.112/') @temporary_media_root() diff --git a/omaha_server/omaha/urls.py b/omaha_server/omaha/urls.py index 5f6bb8a..db2d07c 100644 --- a/omaha_server/omaha/urls.py +++ b/omaha_server/omaha/urls.py @@ -18,6 +18,7 @@ License for the specific language governing permissions and limitations under the License. """ +from django.conf import settings from django.conf.urls import url from omaha.views import UpdateView @@ -26,11 +27,15 @@ from omaha.views_admin import StatisticsView, StatisticsDetailView, RequestListV urlpatterns = [ url(r'^service/update2$', UpdateView.as_view(), name='update'), - - url(r'^admin/statistics/$', StatisticsView.as_view(), name='omaha_statistics'), - url(r'^admin/statistics/(?P<name>[a-zA-Z0-9_ ]+)/$', StatisticsDetailView.as_view(), - name='omaha_statistics_detail'), - url(r'^admin/statistics/(?P<name>[a-zA-Z0-9_ ]+)/requests/$', RequestListView.as_view(), name='omaha_request_list'), - url(r'^admin/statistics/requests/(?P<pk>\d+)/$', AppRequestDetailView.as_view(), name='omaha_request_detail'), - url(r'^admin/set_timezone/$', TimezoneView.as_view(), name='set_timezone'), ] + + +if settings.IS_PRIVATE: + urlpatterns += [ + url(r'^admin/statistics/$', StatisticsView.as_view(), name='omaha_statistics'), + url(r'^admin/statistics/(?P<name>[a-zA-Z0-9_ ]+)/$', StatisticsDetailView.as_view(), + name='omaha_statistics_detail'), + url(r'^admin/statistics/(?P<name>[a-zA-Z0-9_ ]+)/requests/$', RequestListView.as_view(), name='omaha_request_list'), + url(r'^admin/statistics/requests/(?P<pk>\d+)/$', AppRequestDetailView.as_view(), name='omaha_request_detail'), + url(r'^admin/set_timezone/$', TimezoneView.as_view(), name='set_timezone'), + ] diff --git a/omaha_server/omaha_server/s3utils.py b/omaha_server/omaha_server/s3utils.py index 639d12c..754ef84 100644 --- a/omaha_server/omaha_server/s3utils.py +++ b/omaha_server/omaha_server/s3utils.py @@ -1,6 +1,19 @@ from storages.backends.s3boto import S3BotoStorage +from furl import furl -class StaticS3Storage(S3BotoStorage): + +class BaseS3Storage(S3BotoStorage): + def url(self, name): + url = super(BaseS3Storage, self).url(name) + if not self.querystring_auth: + f = furl(url) + if 'x-amz-security-token' in f.args: + del f.args['x-amz-security-token'] + url = f.url + return url + + +class StaticS3Storage(BaseS3Storage): location = 'static' def url(self, name): @@ -8,3 +21,7 @@ class StaticS3Storage(S3BotoStorage): if name.endswith('/') and not url.endswith('/'): url += '/' return url + + +class S3Storage(BaseS3Storage): + pass diff --git a/omaha_server/omaha_server/settings.py b/omaha_server/omaha_server/settings.py index 1bbe9ca..05ea506 100644 --- a/omaha_server/omaha_server/settings.py +++ b/omaha_server/omaha_server/settings.py @@ -16,6 +16,8 @@ from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS as TCP BASE_DIR = os.path.dirname(os.path.dirname(__file__)) PROJECT_DIR = BASE_DIR +IS_PRIVATE = True if os.getenv('OMAHA_SERVER_PRIVATE') == 'True' else False + TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', @@ -95,19 +97,24 @@ INSTALLED_APPS = ( 'feedback', 'sparkle', 'downloads', + 'healthcheck', ) MIDDLEWARE_CLASSES = ( - '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.common.CommonMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', - 'omaha_server.middlewares.TimezoneMiddleware', ) +if IS_PRIVATE: + MIDDLEWARE_CLASSES = ( + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'omaha_server.middlewares.TimezoneMiddleware', + ) + MIDDLEWARE_CLASSES + ROOT_URLCONF = 'omaha_server.urls' WSGI_APPLICATION = 'omaha_server.wsgi.application' diff --git a/omaha_server/omaha_server/settings_prod.py b/omaha_server/omaha_server/settings_prod.py index 21c6b49..392c879 100644 --- a/omaha_server/omaha_server/settings_prod.py +++ b/omaha_server/omaha_server/settings_prod.py @@ -11,7 +11,7 @@ ALLOWED_HOSTS = (os.environ.get('HOST_NAME'), '*') SECRET_KEY = os.environ.get('SECRET_KEY') or crypto.get_random_string(50) STATICFILES_STORAGE = 'omaha_server.s3utils.StaticS3Storage' -DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage' +DEFAULT_FILE_STORAGE = 'omaha_server.s3utils.S3Storage' AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID') AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY') diff --git a/omaha_server/omaha_server/settings_test.py b/omaha_server/omaha_server/settings_test.py index 372cb62..fe64f53 100644 --- a/omaha_server/omaha_server/settings_test.py +++ b/omaha_server/omaha_server/settings_test.py @@ -3,6 +3,9 @@ from .settings import * +IS_PRIVATE = True + + class DisableMigrations(object): def __contains__(self, item): @@ -23,7 +26,7 @@ TEST_RUNNER = 'django_nose.NoseTestSuiteRunner' NOSE_ARGS = [ '--with-coverage', - '--cover-package=omaha_server,omaha,crash,feedback,sparkle', + '--cover-package=omaha_server,omaha,crash,feedback,sparkle,healthcheck', '--cover-inclusive', # '--with-doctest', ] diff --git a/omaha_server/omaha_server/urls.py b/omaha_server/omaha_server/urls.py index 7dab814..c9b77fc 100644 --- a/omaha_server/omaha_server/urls.py +++ b/omaha_server/omaha_server/urls.py @@ -28,22 +28,27 @@ urlpatterns = [ url(r'', include('omaha.urls')), url(r'', include('crash.urls')), url(r'', include('feedback.urls')), - url(r'', include('downloads.urls')), + url(r'^healthcheck/', include('healthcheck.urls')), url(r'^sparkle/', include('sparkle.urls')), - url(r'^admin/', include(admin.site.urls)), - url(r'^api/statistics/channels/(?P<app_name>[a-zA-Z0-9_ ]+)/$', omaha.api.StatisticsChannelsView.as_view(), - name="api-statistics-channels"), - url(r'^api/statistics/versions/(?P<app_name>[a-zA-Z0-9_ ]+)/$', omaha.api.StatisticsVersionsView.as_view(), - name="api-statistics-versions"), - url(r'^api/statistics/months/(?P<app_name>[a-zA-Z0-9_ ]+)/$', omaha.api.StatisticsMonthsDetailView.as_view(), - name="api-statistics-months-detail"), - url(r'^api/statistics/months/$', omaha.api.StatisticsMonthsListView.as_view(), name="api-statistics-months-list"), - url(r'^api/version', omaha.api.ServerVersionView.as_view(), name='api-version'), - url(r'^api/', include(router.urls)), - url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')), - url(r'^select2/', include('django_select2.urls')), ] +if settings.IS_PRIVATE: + urlpatterns += [ + url(r'', include('downloads.urls')), + url(r'^admin/', include(admin.site.urls)), + url(r'^api/statistics/channels/(?P<app_name>[a-zA-Z0-9_ ]+)/$', omaha.api.StatisticsChannelsView.as_view(), + name="api-statistics-channels"), + url(r'^api/statistics/versions/(?P<app_name>[a-zA-Z0-9_ ]+)/$', omaha.api.StatisticsVersionsView.as_view(), + name="api-statistics-versions"), + url(r'^api/statistics/months/(?P<app_name>[a-zA-Z0-9_ ]+)/$', omaha.api.StatisticsMonthsDetailView.as_view(), + name="api-statistics-months-detail"), + url(r'^api/statistics/months/$', omaha.api.StatisticsMonthsListView.as_view(), name="api-statistics-months-list"), + url(r'^api/version', omaha.api.ServerVersionView.as_view(), name='api-version'), + url(r'^api/', include(router.urls)), + url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')), + url(r'^select2/', include('django_select2.urls')), + ] + if settings.DEBUG: try: import debug_toolbar diff --git a/pavement.py b/pavement.py index 9d42e6c..b637df3 100644 --- a/pavement.py +++ b/pavement.py @@ -20,12 +20,17 @@ the License. import os +from raven import Client from paver.easy import task from paver.easy import sh +client = Client(os.environ.get('RAVEN_DNS')) + + @task def test(): + os.environ["OMAHA_SERVER_PRIVATE"] = 'True' sh('./manage.py test --settings=omaha_server.settings_test', cwd='omaha_server') @@ -70,23 +75,69 @@ def create_admin(): @task -def mount_s3(): - kwargs = dict(bucket=os.environ['AWS_STORAGE_BUCKET_NAME'], - mount_point='/srv/omaha_s3') - env = dict(AWSACCESSKEYID=os.environ['AWS_ACCESS_KEY_ID'], - AWSSECRETACCESSKEY=os.environ['AWS_SECRET_ACCESS_KEY']) - cmd = 's3fs {bucket} {mount_point} -ouse_cache=/tmp'.format(**kwargs) - sh(cmd, env=env) +def create_db_public_user(): + import psycopg2 + + db_public_user = os.environ['DB_PUBLIC_USER'] + db_public_password = os.environ['DB_PUBLIC_PASSWORD'] + + conn = psycopg2.connect(host=os.environ['DB_HOST'], + user=os.environ['DB_USER'], + password=os.environ['DB_PASSWORD'], + database=os.environ['DB_NAME']) + curs = conn.cursor() + + try: + # user and group + curs.execute("CREATE USER %s WITH PASSWORD '%s';" % (db_public_user, db_public_password)) + curs.execute('CREATE GROUP public_users WITH USER %s;' % db_public_user) + + # versions + curs.execute('GRANT SELECT ON TABLE applications, platforms, platforms_id_seq, ' + 'channels, channels_id_seq, versions, versions_id_seq, actions, ' + 'actions_id_seq, omaha_data, omaha_data_id_seq, omaha_partialupdate, ' + 'omaha_partialupdate_id_seq, sparkle_sparkleversion, ' + 'sparkle_sparkleversion_id_seq TO GROUP public_users;') + + # crash + curs.execute('GRANT SELECT, INSERT, UPDATE ON TABLE crash_crash, crash_crash_id_seq, ' + 'crash_crashdescription, crash_crashdescription_id_seq TO GROUP public_users;') + curs.execute('GRANT SELECT ON TABLE crash_symbols, crash_symbols_id_seq TO GROUP public_users;') + curs.execute('GRANT INSERT ON TABLE feedback_feedback, feedback_feedback_id_seq TO GROUP public_users;') + + # statistics + curs.execute('GRANT SELECT, INSERT, UPDATE ON TABLE omaha_apprequest, ' + 'omaha_apprequest_id_seq, omaha_apprequest_events, ' + 'omaha_apprequest_events_id_seq, omaha_event, omaha_event_id_seq, omaha_hw, ' + 'omaha_hw_id_seq, omaha_os, omaha_os_id_seq, omaha_request, ' + 'omaha_request_id_seq TO GROUP public_users;') + + # dev + curs.execute('GRANT INSERT ON TABLE httplog_entry, httplog_entry_id_seq TO GROUP public_users;') + conn.commit() + except psycopg2.ProgrammingError: + pass + finally: + curs.close() + conn.close() @task def docker_run(): - migrate() - loaddata() - create_admin() - collectstatic() - # mount_s3() - sh('/usr/bin/supervisord') + try: + is_private = True if os.environ.get('OMAHA_SERVER_PRIVATE') == 'True' else False + + if is_private: + migrate() + create_db_public_user() + loaddata() + create_admin() + collectstatic() + + sh('/usr/bin/supervisord') + except: + client.captureException() + raise @task |