forked from luci/luci-py
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathservices.py
More file actions
94 lines (70 loc) · 2.64 KB
/
services.py
File metadata and controls
94 lines (70 loc) · 2.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# Copyright 2015 The LUCI Authors. All rights reserved.
# Use of this source code is governed by the Apache v2.0 license that can be
# found in the LICENSE file.
"""Provides info about registered luci services."""
from google.appengine.ext import ndb
from components import config
from components import net
from components import utils
from components.config.proto import service_config_pb2
import common
import storage
import validation
class DynamicMetadataError(Exception):
"""Raised when a service metadata endpoint response is bad."""
class ServiceNotFoundError(Exception):
"""Raised when a service is not found."""
@ndb.tasklet
def get_services_async():
"""Returns a list of registered luci services.
The list is stored in services/luci-config:services.cfg. Never returns None.
Cached.
Returns:
A list of service_config_pb2.Service.
"""
cfg = yield storage.get_self_config_async(
common.SERVICES_REGISTRY_FILENAME, service_config_pb2.ServicesCfg)
raise ndb.Return(cfg.services or [])
@ndb.tasklet
def get_service_async(service_id):
"""Returns a service config by id.
Returns:
service_config_pb2.Service, or None if not found.
"""
services = yield get_services_async()
for service in services:
if service.id == service_id:
raise ndb.Return(service)
def _dict_to_dynamic_metadata(data):
validation.validate_service_dynamic_metadata_blob(
data,
config.validation.Context.raise_on_error(exc_type=DynamicMetadataError))
metadata = service_config_pb2.ServiceDynamicMetadata()
validation_meta = data.get('validation')
if validation_meta:
metadata.validation.url = validation_meta['url']
for p in validation_meta.get('patterns', []):
pattern = metadata.validation.patterns.add()
pattern.config_set=p['config_set']
pattern.path=p['path']
return metadata
@utils.memcache_async('service_metadata', ['service_id'], time=60)
@ndb.tasklet
def get_metadata_async(service_id):
"""Returns service dynamic metadata.
Memcaches results for 1 min. Never returns None.
Raises:
ServiceNotFoundError if service |service_id| is not found.
DynamicMetadataError if metadata endpoint response is bad.
"""
service = yield get_service_async(service_id)
if service is None:
raise ServiceNotFoundError('Service "%s" not found', service_id)
if not service.metadata_url:
raise ndb.Return(service_config_pb2.ServiceDynamicMetadata())
try:
res = yield net.json_request_async(
service.metadata_url, scopes=net.EMAIL_SCOPE)
except net.Error as ex:
raise DynamicMetadataError('Net error: %s' % ex.message)
raise ndb.Return(_dict_to_dynamic_metadata(res))