##// END OF EJS Templates
Closed
Pull request !2235 Created on Sat, 13 Oct 2018 19:27:30, by
  • ini: added new key
  • registration: add a way to disable registration
  • Update register.jinja2
  • alert_channels: it should also be a pkey
  • alert_channels: allow binding to resources
Pull request versions not available.
ver Time Author Commit Description
13 commits hidden, click expand to show them.
@@ -13,6 +13,8 b' sqlalchemy.echo = false'
13 jinja2.directories = appenlight:templates
13 jinja2.directories = appenlight:templates
14 jinja2.filters = nl2br = appenlight.lib.jinja2_filters.nl2br
14 jinja2.filters = nl2br = appenlight.lib.jinja2_filters.nl2br
15
15
16 appenlight.disable_registration = false
17
16 #includes
18 #includes
17 appenlight.includes =
19 appenlight.includes =
18
20
@@ -84,6 +84,11 b' def main(global_config, **settings):'
84 encryption.ENCRYPTION_SECRET = settings.get('encryption_secret')
84 encryption.ENCRYPTION_SECRET = settings.get('encryption_secret')
85 # import this later so encyption key can be monkeypatched
85 # import this later so encyption key can be monkeypatched
86 from appenlight.models import DBSession, register_datastores
86 from appenlight.models import DBSession, register_datastores
87
88 # registration
89 settings['appenlight.disable_registration'] = asbool(
90 settings.get('appenlight.disable_registration'))
91
87 # update config with cometd info
92 # update config with cometd info
88 settings['cometd_servers'] = {'server': settings['cometd.server'],
93 settings['cometd_servers'] = {'server': settings['cometd.server'],
89 'secret': settings['cometd.secret']}
94 'secret': settings['cometd.secret']}
@@ -176,6 +176,10 b' def register(request):'
176 if request.method == 'POST' and form.validate():
176 if request.method == 'POST' and form.validate():
177 log.info('registering user')
177 log.info('registering user')
178 # insert new user here
178 # insert new user here
179 if request.registry.settings['appenlight.disable_registration']:
180 request.session.flash(_('Registration is currently disabled.'))
181 return HTTPFound(location=request.route_url('/'))
182
179 new_user = User()
183 new_user = User()
180 DBSession.add(new_user)
184 DBSession.add(new_user)
181 form.populate_obj(new_user)
185 form.populate_obj(new_user)
@@ -79,6 +79,10 b' def users_create(request):'
79 csrf_context=request)
79 csrf_context=request)
80 if form.validate():
80 if form.validate():
81 log.info('registering user')
81 log.info('registering user')
82 # probably not needed in the future since this requires root anyways
83 # lets keep this here in case we lower view permission in the future
84 # if request.registry.settings['appenlight.disable_registration']:
85 # return HTTPUnprocessableEntity(body={'error': 'Registration is currently disabled.'})
82 user = User()
86 user = User()
83 # insert new user here
87 # insert new user here
84 DBSession.add(user)
88 DBSession.add(user)
@@ -77,6 +77,11 b''
77 {{ widgets.render_form(form) }}
77 {{ widgets.render_form(form) }}
78 <input type="submit" class="btn btn-primary"
78 <input type="submit" class="btn btn-primary"
79 value="Register">
79 value="Register">
80 <p>
81 By clicking "Register", you agree to our
82 <a href="https://getappenlight.com/page/terms-of-service.html">terms of service</a> and
83 <a href="https://getappenlight.com/page/privacy-policy.html">privacy policy</a>.
84 </p>
80 </form>
85 </form>
81 </div>
86 </div>
82 </div>
87 </div>
@@ -19,10 +19,12 b' def upgrade():'
19 'channels_resources',
19 'channels_resources',
20 sa.Column('channel_pkey', sa.Integer,
20 sa.Column('channel_pkey', sa.Integer,
21 sa.ForeignKey('alert_channels.pkey',
21 sa.ForeignKey('alert_channels.pkey',
22 ondelete='CASCADE', onupdate='CASCADE')),
22 ondelete='CASCADE', onupdate='CASCADE'),
23 primary_key=True),
23 sa.Column('resource_id', sa.Integer,
24 sa.Column('resource_id', sa.Integer,
24 sa.ForeignKey('resources.resource_id',
25 sa.ForeignKey('resources.resource_id',
25 ondelete='CASCADE', onupdate='CASCADE'))
26 ondelete='CASCADE', onupdate='CASCADE'),
27 primary_key=True)
26 )
28 )
27
29
28
30
@@ -79,7 +79,7 b' class AlertChannel(Base, BaseModel):'
79 secondary=channel_rules_m2m_table,
79 secondary=channel_rules_m2m_table,
80 backref='channels')
80 backref='channels')
81 resources = sa.orm.relationship('Resource',
81 resources = sa.orm.relationship('Resource',
82 cascade="all, delete-orphan",
82 cascade="all",
83 passive_deletes=True,
83 passive_deletes=True,
84 passive_updates=True,
84 passive_updates=True,
85 secondary=channel_resources_m2m_table,
85 secondary=channel_resources_m2m_table,
@@ -0,0 +1,30 b''
1 """connect resources to alert_channels
2
3 Revision ID: e9fcfbdd9498
4 Revises: 55b6e612672f
5 Create Date: 2018-02-28 13:52:50.717217
6
7 """
8
9 # revision identifiers, used by Alembic.
10 revision = 'e9fcfbdd9498'
11 down_revision = '55b6e612672f'
12
13 from alembic import op
14 import sqlalchemy as sa
15
16
17 def upgrade():
18 op.create_table(
19 'channels_resources',
20 sa.Column('channel_pkey', sa.Integer,
21 sa.ForeignKey('alert_channels.pkey',
22 ondelete='CASCADE', onupdate='CASCADE')),
23 sa.Column('resource_id', sa.Integer,
24 sa.ForeignKey('resources.resource_id',
25 ondelete='CASCADE', onupdate='CASCADE'))
26 )
27
28
29 def downgrade():
30 op.drop_table('channels_resources')
@@ -34,6 +34,14 b' channel_rules_m2m_table = sa.Table('
34 sa.ForeignKey('alert_channels_actions.pkey'))
34 sa.ForeignKey('alert_channels_actions.pkey'))
35 )
35 )
36
36
37 channel_resources_m2m_table = sa.Table(
38 'channels_resources', Base.metadata,
39 sa.Column('channel_pkey', sa.Integer,
40 sa.ForeignKey('alert_channels.pkey')),
41 sa.Column('resource_id', sa.Integer,
42 sa.ForeignKey('resources.resource_id'))
43 )
44
37 DATE_FRMT = '%Y-%m-%dT%H:%M'
45 DATE_FRMT = '%Y-%m-%dT%H:%M'
38
46
39
47
@@ -70,6 +78,12 b' class AlertChannel(Base, BaseModel):'
70 passive_updates=True,
78 passive_updates=True,
71 secondary=channel_rules_m2m_table,
79 secondary=channel_rules_m2m_table,
72 backref='channels')
80 backref='channels')
81 resources = sa.orm.relationship('Resource',
82 cascade="all, delete-orphan",
83 passive_deletes=True,
84 passive_updates=True,
85 secondary=channel_resources_m2m_table,
86 backref='resources')
73
87
74 @property
88 @property
75 def channel_visible_value(self):
89 def channel_visible_value(self):
@@ -92,7 +92,12 b' class Event(Base, BaseModel):'
92 users = set([p.user for p in resource.users_for_perm('view')])
92 users = set([p.user for p in resource.users_for_perm('view')])
93 for user in users:
93 for user in users:
94 for channel in user.alert_channels:
94 for channel in user.alert_channels:
95 if not channel.channel_validated or not channel.send_alerts:
95 matches_resource = not channel.resources or resource in [r.resource_id for r in channel.resources]
96 if (
97 not channel.channel_validated or
98 not channel.send_alerts or
99 not matches_resource
100 ):
96 continue
101 continue
97 else:
102 else:
98 try:
103 try:
@@ -0,0 +1,30 b''
1 """connect resources to alert_channels
2
3 Revision ID: e9fcfbdd9498
4 Revises: 55b6e612672f
5 Create Date: 2018-02-28 13:52:50.717217
6
7 """
8
9 # revision identifiers, used by Alembic.
10 revision = 'e9fcfbdd9498'
11 down_revision = '55b6e612672f'
12
13 from alembic import op
14 import sqlalchemy as sa
15
16
17 def upgrade():
18 op.create_table(
19 'channels_resources',
20 sa.Column('channel_pkey', sa.Integer,
21 sa.ForeignKey('alert_channels.pkey',
22 ondelete='CASCADE', onupdate='CASCADE')),
23 sa.Column('resource_id', sa.Integer,
24 sa.ForeignKey('resources.resource_id',
25 ondelete='CASCADE', onupdate='CASCADE'))
26 )
27
28
29 def downgrade():
30 op.drop_table('channels_resources')
@@ -34,6 +34,14 b' channel_rules_m2m_table = sa.Table('
34 sa.ForeignKey('alert_channels_actions.pkey'))
34 sa.ForeignKey('alert_channels_actions.pkey'))
35 )
35 )
36
36
37 channel_resources_m2m_table = sa.Table(
38 'channels_resources', Base.metadata,
39 sa.Column('channel_pkey', sa.Integer,
40 sa.ForeignKey('alert_channels.pkey')),
41 sa.Column('resource_id', sa.Integer,
42 sa.ForeignKey('resources.resource_id'))
43 )
44
37 DATE_FRMT = '%Y-%m-%dT%H:%M'
45 DATE_FRMT = '%Y-%m-%dT%H:%M'
38
46
39
47
@@ -70,6 +78,12 b' class AlertChannel(Base, BaseModel):'
70 passive_updates=True,
78 passive_updates=True,
71 secondary=channel_rules_m2m_table,
79 secondary=channel_rules_m2m_table,
72 backref='channels')
80 backref='channels')
81 resources = sa.orm.relationship('Resource',
82 cascade="all, delete-orphan",
83 passive_deletes=True,
84 passive_updates=True,
85 secondary=channel_resources_m2m_table,
86 backref='resources')
73
87
74 @property
88 @property
75 def channel_visible_value(self):
89 def channel_visible_value(self):
@@ -92,7 +92,12 b' class Event(Base, BaseModel):'
92 users = set([p.user for p in resource.users_for_perm('view')])
92 users = set([p.user for p in resource.users_for_perm('view')])
93 for user in users:
93 for user in users:
94 for channel in user.alert_channels:
94 for channel in user.alert_channels:
95 if not channel.channel_validated or not channel.send_alerts:
95 matches_resource = not channel.resources or resource in [r.resource_id for r in channel.resources]
96 if (
97 not channel.channel_validated or
98 not channel.send_alerts or
99 not matches_resource
100 ):
96 continue
101 continue
97 else:
102 else:
98 try:
103 try:
@@ -141,7 +141,7 b' def update_template():'
141 "settings": {
141 "settings": {
142 "index": {
142 "index": {
143 "refresh_interval": "5s",
143 "refresh_interval": "5s",
144 "translog": {"interval": "5s",
144 "translog": {"sync_interval": "5s",
145 "durability": "async"}
145 "durability": "async"}
146 },
146 },
147 "number_of_shards": 5,
147 "number_of_shards": 5,
@@ -43,7 +43,7 b' from appenlight.lib import cache_regions'
43 from appenlight.lib.ext_json import json
43 from appenlight.lib.ext_json import json
44 from appenlight.security import groupfinder, AuthTokenAuthenticationPolicy
44 from appenlight.security import groupfinder, AuthTokenAuthenticationPolicy
45
45
46 __license__ = 'AGPLv3, and Commercial License'
46 __license__ = 'Apache 2.0'
47 __author__ = 'RhodeCode GmbH'
47 __author__ = 'RhodeCode GmbH'
48 __url__ = 'http://rhodecode.com'
48 __url__ = 'http://rhodecode.com'
49
49
@@ -4,8 +4,8 b' AppEnlight'
4 Automatic Installation
4 Automatic Installation
5 ======================
5 ======================
6
6
7 Use the ansible scripts in the `/automation` directory to build complete instance of application
7 Use the ansible scripts in the `automation` repository to build complete instance of application
8 You can also use `packer` files in `/automation/packer` to create whole VM's for KVM and VMWare.
8 You can also use `packer` files in `automation/packer` to create whole VM's for KVM and VMWare.
9
9
10 Manual Installation
10 Manual Installation
11 ===================
11 ===================
@@ -13,7 +13,7 b' Manual Installation'
13 To run the app you need to have meet prerequsites:
13 To run the app you need to have meet prerequsites:
14
14
15 - python 3.5+
15 - python 3.5+
16 - running elasticsearch (2.3+ tested)
16 - running elasticsearch (2.3+/2.4 tested)
17 - running postgresql (9.5+ required)
17 - running postgresql (9.5+ required)
18 - running redis
18 - running redis
19
19
@@ -23,7 +23,7 b' Install the app by performing'
23
23
24 python setup.py develop
24 python setup.py develop
25
25
26 Install the appenlight uptime plugin (`ae_uptime_ce` package).
26 Install the appenlight uptime plugin (`ae_uptime_ce` package from `appenlight-uptime-ce` repository).
27
27
28 After installing the application you need to perform following steps:
28 After installing the application you need to perform following steps:
29
29
@@ -0,0 +1,220 b''
1 # Created by .ignore support plugin (hsz.mobi)
2 ### Node template
3 # Logs
4 logs
5 *.log
6 npm-debug.log*
7 yarn-debug.log*
8 yarn-error.log*
9
10 # Runtime data
11 pids
12 *.pid
13 *.seed
14 *.pid.lock
15
16 # Directory for instrumented libs generated by jscoverage/JSCover
17 lib-cov
18
19 # Coverage directory used by tools like istanbul
20 coverage
21
22 # nyc test coverage
23 .nyc_output
24
25 # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
26 .grunt
27
28 # Bower dependency directory (https://bower.io/)
29 bower_components
30
31 # node-waf configuration
32 .lock-wscript
33
34 # Compiled binary addons (https://nodejs.org/api/addons.html)
35 build/Release
36
37 # Dependency directories
38 node_modules/
39 jspm_packages/
40
41 # Typescript v1 declaration files
42 typings/
43
44 # Optional npm cache directory
45 .npm
46
47 # Optional eslint cache
48 .eslintcache
49
50 # Optional REPL history
51 .node_repl_history
52
53 # Output of 'npm pack'
54 *.tgz
55
56 # Yarn Integrity file
57 .yarn-integrity
58
59 # dotenv environment variables file
60 .env
61
62 ### JetBrains template
63 # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
64 # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
65
66 # User-specific stuff:
67 .idea/**/workspace.xml
68 .idea/**/tasks.xml
69 .idea/dictionaries
70
71 # Sensitive or high-churn files:
72 .idea/**/dataSources/
73 .idea/**/dataSources.ids
74 .idea/**/dataSources.xml
75 .idea/**/dataSources.local.xml
76 .idea/**/sqlDataSources.xml
77 .idea/**/dynamic.xml
78 .idea/**/uiDesigner.xml
79
80 # Gradle:
81 .idea/**/gradle.xml
82 .idea/**/libraries
83
84 # CMake
85 cmake-build-debug/
86
87 # Mongo Explorer plugin:
88 .idea/**/mongoSettings.xml
89
90 ## File-based project format:
91 *.iws
92
93 ## Plugin-specific files:
94
95 # IntelliJ
96 out/
97
98 # mpeltonen/sbt-idea plugin
99 .idea_modules/
100
101 # JIRA plugin
102 atlassian-ide-plugin.xml
103
104 # Cursive Clojure plugin
105 .idea/replstate.xml
106
107 # Crashlytics plugin (for Android Studio and IntelliJ)
108 com_crashlytics_export_strings.xml
109 crashlytics.properties
110 crashlytics-build.properties
111 fabric.properties
112 ### Python template
113 # Byte-compiled / optimized / DLL files
114 __pycache__/
115 *.py[cod]
116 *$py.class
117
118 # C extensions
119 *.so
120
121 # Distribution / packaging
122 .Python
123 build/
124 develop-eggs/
125 dist/
126 downloads/
127 eggs/
128 .eggs/
129 lib/
130 lib64/
131 parts/
132 sdist/
133 var/
134 wheels/
135 *.egg-info/
136 .installed.cfg
137 *.egg
138 MANIFEST
139
140 # PyInstaller
141 # Usually these files are written by a python script from a template
142 # before PyInstaller builds the exe, so as to inject date/other infos into it.
143 *.manifest
144 *.spec
145
146 # Installer logs
147 pip-log.txt
148 pip-delete-this-directory.txt
149
150 # Unit test / coverage reports
151 htmlcov/
152 .tox/
153 .coverage
154 .coverage.*
155 .cache
156 nosetests.xml
157 coverage.xml
158 *.cover
159 .hypothesis/
160
161 # Translations
162 *.mo
163 *.pot
164
165 # Django stuff:
166 local_settings.py
167
168 # Flask stuff:
169 instance/
170 .webassets-cache
171
172 # Scrapy stuff:
173 .scrapy
174
175 # Sphinx documentation
176 docs/_build/
177
178 # PyBuilder
179 target/
180
181 # Jupyter Notebook
182 .ipynb_checkpoints
183
184 # pyenv
185 .python-version
186
187 # celery beat schedule file
188 celerybeat-schedule
189
190 # SageMath parsed files
191 *.sage.py
192
193 # Environments
194 .venv
195 env/
196 venv/
197 ENV/
198 env.bak/
199 venv.bak/
200
201 # Spyder project settings
202 .spyderproject
203 .spyproject
204
205 # Rope project settings
206 .ropeproject
207
208 # mkdocs documentation
209 /site
210
211 # mypy
212 .mypy_cache/
213 ### Example user template template
214 ### Example user template
215
216 # IntelliJ project files
217 .idea
218 *.iml
219 out
220 gen
@@ -1,5 +1,5 b''
1 [bumpversion]
1 [bumpversion]
2 current_version = 1.0.0
2 current_version = 1.1.0
3 message = release: Bump version {current_version} to {new_version}
3 message = release: Bump version {current_version} to {new_version}
4 tag_name = {new_version}
4 tag_name = {new_version}
5
5
@@ -1,1 +1,1 b''
1 1.0.0
1 1.1.0
General Comments 2
Under Review
author

Auto status change to "Under Review"

Rejected

Please use: https://github.com/Appenlight/appenlight to contribute :) Thanks !