Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(134)

Side by Side Diff: appengine/auth_service/config.py

Issue 2164733003: auth: Keep audit log of all generated delegation tokens. (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/luci-py@master
Patch Set: auth: Keep audit log of all generates delegation tokens. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | appengine/auth_service/config_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2015 The LUCI Authors. All rights reserved. 1 # Copyright 2015 The LUCI Authors. All rights reserved.
2 # Use of this source code is governed under the Apache License, Version 2.0 2 # Use of this source code is governed under the Apache License, Version 2.0
3 # that can be found in the LICENSE file. 3 # that can be found in the LICENSE file.
4 4
5 """Adapter between config service client and the rest of auth_service. 5 """Adapter between config service client and the rest of auth_service.
6 6
7 Basically a cron job that each minute refetches config files from config service 7 Basically a cron job that each minute refetches config files from config service
8 and modifies auth service datastore state if anything changed. 8 and modifies auth service datastore state if anything changed.
9 9
10 Following files are fetched: 10 Following files are fetched:
11 imports.cfg - configuration for group importer cron job. 11 imports.cfg - configuration for group importer cron job.
12 ip_whitelist.cfg - IP whitelists. 12 ip_whitelist.cfg - IP whitelists.
13 oauth.cfg - OAuth client_id whitelist. 13 oauth.cfg - OAuth client_id whitelist.
14 14
15 Configs are ASCII serialized protocol buffer messages. The schema is defined in 15 Configs are ASCII serialized protocol buffer messages. The schema is defined in
16 proto/config.proto. 16 proto/config.proto.
17 17
18 Storing infrequently changing configuration in the config service (implemented 18 Storing infrequently changing configuration in the config service (implemented
19 on top of source control) allows to use code review workflow for configuration 19 on top of source control) allows to use code review workflow for configuration
20 changes as well as removes a need to write some UI for them. 20 changes as well as removes a need to write some UI for them.
21 """ 21 """
22 22
23 import collections 23 import collections
24 import logging 24 import logging
25 import os
26 import posixpath 25 import posixpath
27 26
28 from google import protobuf 27 from google import protobuf
29 from google.appengine.ext import ndb 28 from google.appengine.ext import ndb
30 29
31 from components import config 30 from components import config
32 from components import datastore_utils 31 from components import datastore_utils
33 from components import gitiles 32 from components import gitiles
34 from components import utils 33 from components import utils
35 from components.auth import ipaddr 34 from components.auth import ipaddr
36 from components.auth import model 35 from components.auth import model
37 from components.config import validation 36 from components.config import validation
38 from components.config import validation_context 37 from components.config import validation_context
39 38
40 from proto import config_pb2 39 from proto import config_pb2
41 import importer 40 import importer
42 41
43 42
44 # Config file revision number and where it came from. 43 # Config file revision number and where it came from.
45 Revision = collections.namedtuple('Revision', ['revision', 'url']) 44 Revision = collections.namedtuple('Revision', ['revision', 'url'])
46 45
47 46
47 class CannotLoadConfigError(Exception):
48 """Raised when fetching configs if they are missing or invalid."""
49
50
48 def is_remote_configured(): 51 def is_remote_configured():
49 """True if config service backend URL is defined. 52 """True if config service backend URL is defined.
50 53
51 If config service backend URL is not set auth_service will use datastore 54 If config service backend URL is not set auth_service will use datastore
52 as source of truth for configuration (with some simple web UI to change it). 55 as source of truth for configuration (with some simple web UI to change it).
53 56
54 If config service backend URL is set, UI for config management will be read 57 If config service backend URL is set, UI for config management will be read
55 only and all config changes must be performed through the config service. 58 only and all config changes must be performed through the config service.
56 """ 59 """
57 return bool(get_remote_url()) 60 return bool(get_remote_url())
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 100
98 Called as a cron job. 101 Called as a cron job.
99 """ 102 """
100 if not is_remote_configured(): 103 if not is_remote_configured():
101 logging.info('Config remote is not configured') 104 logging.info('Config remote is not configured')
102 return 105 return
103 106
104 # Grab and validate all new configs in parallel. 107 # Grab and validate all new configs in parallel.
105 try: 108 try:
106 configs = _fetch_configs(_CONFIG_SCHEMAS) 109 configs = _fetch_configs(_CONFIG_SCHEMAS)
107 except config.CannotLoadConfigError as exc: 110 except CannotLoadConfigError as exc:
108 logging.error('Failed to fetch configs\n%s', exc) 111 logging.error('Failed to fetch configs\n%s', exc)
109 return 112 return
110 113
111 # Figure out what needs to be updated. 114 # Figure out what needs to be updated.
112 dirty = {} 115 dirty = {}
113 dirty_in_authdb = {} 116 dirty_in_authdb = {}
114 for path, (new_rev, conf) in sorted(configs.iteritems()): 117 for path, (new_rev, conf) in sorted(configs.iteritems()):
115 assert path in _CONFIG_SCHEMAS, path 118 assert path in _CONFIG_SCHEMAS, path
116 cur_rev = get_config_revision(path) 119 cur_rev = get_config_revision(path)
117 if cur_rev != new_rev or force: 120 if cur_rev != new_rev or force:
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 config.get_self_config_async( 530 config.get_self_config_async(
528 p, dest_type=_CONFIG_SCHEMAS[p]['proto_class'], store_last_good=False) 531 p, dest_type=_CONFIG_SCHEMAS[p]['proto_class'], store_last_good=False)
529 for p in paths 532 for p in paths
530 ] 533 ]
531 configs_url = _get_configs_url() 534 configs_url = _get_configs_url()
532 ndb.Future.wait_all(futures) 535 ndb.Future.wait_all(futures)
533 out = {} 536 out = {}
534 for path, future in zip(paths, futures): 537 for path, future in zip(paths, futures):
535 rev, conf = future.get_result() 538 rev, conf = future.get_result()
536 if conf is None: 539 if conf is None:
537 raise config.CannotLoadConfigError('Config %s is missing' % path) 540 raise CannotLoadConfigError('Config %s is missing' % path)
538 try: 541 try:
539 validation.validate(config.self_config_set(), path, conf) 542 validation.validate(config.self_config_set(), path, conf)
540 except ValueError as exc: 543 except ValueError as exc:
541 raise config.CannotLoadConfigError( 544 raise CannotLoadConfigError(
542 'Config %s at rev %s failed to pass validation: %s' % 545 'Config %s at rev %s failed to pass validation: %s' %
543 (path, rev, exc)) 546 (path, rev, exc))
544 out[path] = (Revision(rev, _gitiles_url(configs_url, rev, path)), conf) 547 out[path] = (Revision(rev, _gitiles_url(configs_url, rev, path)), conf)
545 return out 548 return out
546 549
547 550
548 def _gitiles_url(configs_url, rev, path): 551 def _gitiles_url(configs_url, rev, path):
549 """URL to a directory in gitiles -> URL to a file at concrete revision.""" 552 """URL to a directory in gitiles -> URL to a file at concrete revision."""
550 try: 553 try:
551 location = gitiles.Location.parse(configs_url) 554 location = gitiles.Location.parse(configs_url)
552 return str(gitiles.Location( 555 return str(gitiles.Location(
553 hostname=location.hostname, 556 hostname=location.hostname,
554 project=location.project, 557 project=location.project,
555 treeish=rev, 558 treeish=rev,
556 path=posixpath.join(location.path, path))) 559 path=posixpath.join(location.path, path)))
557 except ValueError: 560 except ValueError:
558 # Not a gitiles URL, return as is. 561 # Not a gitiles URL, return as is.
559 return configs_url 562 return configs_url
OLDNEW
« no previous file with comments | « no previous file | appengine/auth_service/config_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698