go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/common/proto/config/service_config.proto (about) 1 // Copyright 2015 The LUCI Authors. All rights reserved. 2 // Use of this source code is governed under the Apache License, Version 2.0 3 // that can be found in the LICENSE file. 4 5 // Schemas for config files in services/luci-config config set. 6 // 7 // In this file, "string pattern" is an exact string (can't have a colon) or a 8 // string that starts with "regex:", followed by a regular expression. In case 9 // of regex, the pattern must match an entire string, as if it was surrounded by 10 // ^ and $. 11 12 syntax = "proto3"; 13 14 package config; 15 16 import "google/protobuf/empty.proto"; 17 18 option go_package = "go.chromium.org/luci/common/proto/config"; 19 20 21 // Use to specify configuration stored in Git repository importable via Gitiles 22 // API. 23 message GitilesLocation { 24 // URL of the Git repository. 25 // Must not end with "/". 26 // Must not end with ".git". 27 // Must not have "/a/" prefix of a path component. 28 // 29 // Example: 30 // OK: 31 // https://chromium.googlesource.com/infra/infra 32 // Not OK: 33 // https://chromium.googlesource.com/a/infra/infra 34 // https://chromium.googlesource.com/infra/infra/ 35 // https://chromium.googlesource.com/infra/infra.git 36 string repo = 1; 37 // Ref or commit hash of the Git repository. 38 // 39 // Must be a fully qualified ref starting with "refs/" or a commit hash. 40 // 41 // Example: 42 // OK: 43 // refs/heads/branch 44 // refs/heads/infra/config 45 // refs/branch-heads/beta 46 // $a_valid_git_sha 47 // Not OK: 48 // main 49 // HEAD 50 // origin/main 51 // tags/123 52 // 53 // TODO: crbug/1446839 - Replace this field with a new `committish` field 54 // to better reflect the fact that field value can be either refs or 55 // revision hash. 56 string ref = 2; 57 // Path to the directory inside Git repository where configurations are stored. 58 // Optional. If not specified, defaults to top-level folder of the git repo. 59 // Must not start or end with "/". 60 // 61 // Example: 62 // OK: 63 // infra/config/generated 64 // (empty string) 65 // NOT OK: 66 // / 67 // /config 68 // infra/config/ 69 string path = 3; 70 } 71 72 // Used to define project specific identities for LUCI to act on behalf when 73 // interacting with external systems. This allows projects to use exclusive 74 // and isolated identities to not be accidentally affected by other projects. 75 message IdentityConfig { 76 // ServiceAccountEmail is the full service account email to use when 77 // LUCI acts on behalf of the project. 78 // 79 // Note: Due to token caching, it takes ~15 minutes for a config change 80 // to become effective. Keep this in mind when migrating projects to a 81 // new identity. 82 string service_account_email = 1; 83 } 84 85 // Location is the source repo location where the configuration stores. 86 // Currently, it only supports Gitiles repos. 87 // TODO(crbug.com/1446839): replace Project.gitiles_location field later. 88 message Location { 89 oneof location { 90 GitilesLocation gitiles_location = 1; 91 } 92 } 93 94 /******************************************************************************/ 95 /* Projects */ 96 /******************************************************************************/ 97 98 // A tenant of a service. Defined in projects.cfg. 99 message Project { 100 reserved 2; 101 reserved 'config_location'; 102 103 // Globally unique id of the project. 104 // 105 // The id MUST contain only lowercase alphanumeric characters and hyphens. 106 // The id MUST NOT be empty or exceed 30 characters. 107 string id = 1; 108 109 // Where to import "projects/<id>" config set from. 110 oneof location { 111 GitilesLocation gitiles_location = 4; 112 } 113 114 // IdentityConfig determines what identities are used when LUCI acts on 115 // behalf of the project towards external services. 116 IdentityConfig identity_config = 3; 117 118 // The Team `name` of the Team which owns this Project. 119 // 120 // Note that the same Team may be indicated for multiple different Projects. 121 string owned_by = 5; 122 } 123 124 // Represents a group of humans who are responsible for one or more LUCI 125 // projects. 126 // 127 // LUCI system maintainers will use the contact addresses associated with 128 // this Team in order to contact that group of humans about maintenance actions 129 // which this Team needs to perform in order to keep current with LUCI. 130 // 131 // We recommend subscribing to the following mailing lists as well: 132 // * luci-announce@ - Announcements of new LUCI functionality. 133 // * luci-outages@ - Announcements of LUCI system outages/downtime. 134 // * luci-releases@ - (noisy) Announcements of new LUCI service deployments. 135 // 136 // We also recommend directing LUCI questions/discussion to: 137 // * go/luci-users-chat - Chatroom open to all users of LUCI. Good place to 138 // ask/answer questions about the use of LUCI services. 139 // * go/luci-dev-chat - Chatroom for developing LUCI services, or 140 // systems which tightly interact with LUCI services. 141 // * luci-eng@ - Email list for LUCI related questions. 142 // 143 // Bugs should be filed to: 144 // * go/bug-a-trooper - General bug reports related to the operation of 145 // specific builders/machines which happen to run in LUCI. This is a general 146 // Chrome-area bug and will be triaged (usually within 24h). 147 // * go/luci-bug - Bug reports/feature requests for LUCI services. 148 // * go/luci-trooper-bug - Bug reports against LUCI services which 149 // need quick attention from a trooper. 150 // * oncall/chrome-ops-foundation - Oncall rotation for ChOps Foundation 151 // (primary responders for LUCI service outages). It's a good idea to check 152 // go/luci-users-chat and luci-outages@ too. 153 // 154 // For some migrations, LUCI system maintainers may need to send CLs against 155 // your project's configuration. The best way to enable this is to maintain an 156 // OWNERS file in your project configuration repo, otherwise we'll have to start 157 // guessing at reviewers :). 158 // 159 // To allow LUCI system maintainers to send CLs, please ensure that eng@ has the 160 // ability to read+send CLs to your configuration repo. If we're unable to send 161 // a CL (e.g. the repo is super-secret), we'll instead send an email for you to 162 // apply the change yourself. 163 message Team { 164 // The name of this team; Used for the Project.team field, but also may 165 // be used in e.g. email as the addressee for maintenance messages, like: 166 // 167 // Hello ${Team.name} LUCI maintainers, 168 // 169 // Examples: 170 // GOOD: "ChOps Foundation" 171 // BAD: "cft" 172 string name = 1; 173 174 // One or more contact emails for this team. 175 // 176 // ALL of these email addresses will be used by the LUCI system owners to 177 // contact the team with maintenance requests/deprecation notices. For 178 // example, if some LUCI functionality is deprecated and needs to be migrated, 179 // then an email would be sent to all contacts listed in this field. 180 // 181 // We recommend setting this to your team's dev-group email. 182 repeated string maintenance_contact = 2; 183 184 // One or more fallback emails for this team. 185 // 186 // If the LUCI system owners attempt to contact the team via 187 // `maintenance_contact` and there's no response, these emails will be 188 // CC'd in increasing order until we get in contact with someone. 189 // 190 // If the LUCI system owners cannot contact anyone in `maintenance_contact` or 191 // in `escalation_contact`, we may need to disable the associated LUCI 192 // project(s). 193 // 194 // We recommend setting this to one or two individual people who are 195 // responsible for your team's LUCI integration, and finally a 196 // wider email group (or groups) than those in maintenance_contact. 197 repeated string escalation_contact = 3; 198 } 199 200 // Schema of projects.cfg file. Represents LUCI tenants registry. 201 message ProjectsCfg { 202 // All projects served by this instance of LUCI. 203 repeated Project projects = 1; 204 205 // All teams which own projects. 206 repeated Team teams = 2; 207 } 208 209 /******************************************************************************/ 210 /* Services */ 211 /******************************************************************************/ 212 213 // Describes one LUCI service. 214 message Service { 215 reserved 3; 216 reserved 'config_location'; 217 218 message JWTAuth { 219 // Value for the 'aud' field in the JSON Web Token claim. 220 string audience = 1; 221 } 222 223 // Globally unique id of the service. Required. 224 // Used in "services/<service_id>" config set name. 225 string id = 1; 226 // Email addresses of responsible and point-of-contacts for the service. 227 repeated string owners = 2; 228 // An HTTPS endpoint that returns JSON-encoded ServiceDynamicMetadata in body. 229 // 230 // TODO: crbug/1232565 - Deprecate this field in favor of `hostname` 231 // after the new LUCI Config service has launched. 232 string metadata_url = 4; 233 // The hostname of the service. 234 // 235 // LUCI Config will call this host to interact with `config.Consumer` 236 // prpc Service. 237 string hostname = 7; 238 // A list of identities that have access to this service's configs. 239 // of: 240 // * "group:<group>", where group is defined on auth server. 241 // * "<email>" 242 // * "<kind>:<value>" (for non-email identities) 243 // 244 // If not specified, only admins and trusted services have access. 245 repeated string access = 5; 246 // If set, use JWT auth in requests to services. This is usually used for 247 // Cloud Endpoints v2 support. 248 JWTAuth jwt_auth = 6; 249 } 250 251 // Machine-generated service metadata, exposed by a service endpoint. 252 // Typically implemented by config component, embedded in an app: 253 // see appengine/components/components/config/endpoint.py 254 // 255 // If you add a field here, also add it to ServiceDynamicMetadata in endpoint.py 256 message ServiceDynamicMetadata { 257 // Format version. Supported versions: 1.0. 258 string version = 1; 259 // What configs this service can validate and how to validate them. 260 Validator validation = 2; 261 // True if the server recognizes "Content-Encoding: gzip" in requests. 262 bool supports_gzip_compression = 3; 263 } 264 265 // Schema of services.cfg 266 message ServicesCfg { 267 // A list of all LUCI services. Should be sorted by id. 268 repeated Service services = 1; 269 } 270 271 /******************************************************************************/ 272 /* Misc */ 273 /******************************************************************************/ 274 275 276 // Schema of acl.cfg file. 277 // Next tag: 13. 278 message AclCfg { 279 reserved 3, 4, 5, 6, 12; 280 reserved 'config_get_by_hash_group'; 281 reserved 'admin_group'; 282 reserved 'validation_group'; 283 reserved 'reimport_group'; 284 reserved 'legacy_project_access_group'; 285 286 // Name of the group that has global access to all "projects/*" config sets. 287 // 288 // Should contain only members that really need read access to multiple 289 // projects. Access to an individual project can be granted through 290 // "role/configs.reader" role in the "@root" realm of the project. 291 string project_access_group = 2; 292 293 // Name of the group that can call validation API for any accessible project. 294 // 295 // Should contain only members that really need to use validation API in 296 // multiple projects. Permission to validate an individual project can be 297 // granted through "role/configs.developer" role in the "@root" realm of 298 // the project. 299 string project_validation_group = 8; 300 301 // Name of the group that can call reimport API for any accessible project. 302 // 303 // Should contain only members that really need to use reimport API in 304 // multiple projects. Permission to reimport an individual project can be 305 // granted through "role/configs.developer" role in the "@root" realm of 306 // the project. 307 string project_reimport_group = 9; 308 309 // Name of the group that has global access to all "services/*" config sets. 310 // 311 // Should contain only members that really need read access to multiple 312 // services. Access to an individual service can be granted via "access" field 313 // in its entry in services.cfg config. 314 string service_access_group = 7; 315 316 // Name of the group that can call validation API for any accessible service. 317 string service_validation_group = 10; 318 319 // Name of the group that can call reimport API for any accessible service. 320 string service_reimport_group = 11; 321 } 322 323 // Schema for import.cfg. It specified how to import configuration files from 324 // external sources. 325 message ImportCfg { 326 327 message Gitiles { 328 // Request timeout in seconds when requesting commit log. 329 int32 fetch_log_deadline = 1; 330 // Request timeout in seconds when requesting directory archive. 331 int32 fetch_archive_deadline = 2; 332 // DEPRECATED, ignored. TODO(nodir): remove. 333 // Default ref for project configs. 334 string project_config_default_ref = 3; 335 // DEPRECATED, ignored. TODO(nodir): remove. 336 // Default directory for project configs. 337 string project_config_default_path = 4; 338 // Default directory for ref configs. 339 string ref_config_default_path = 5; 340 } 341 342 // Configuration of import from Gitiles repositories. 343 Gitiles gitiles = 1; 344 } 345 346 // Schema of schemas.cfg 347 message SchemasCfg { 348 message Schema { 349 // Name of schema. 350 // For service configs, "<config_set>:<path>" 351 // For project configs, "projects:<path>" 352 // For ref configs, "projects/refs:<path>" 353 string name = 1; 354 // URL to the schema definition, e.g. to a .proto file in a repository. 355 string url = 2; 356 } 357 // List of known schemas. They are available at /schemas/<name> as a short 358 // mutable link. 359 repeated Schema schemas = 1; 360 } 361 362 /******************************************************************************/ 363 /* Validation */ 364 /******************************************************************************/ 365 366 // Defines a pattern of a config identity. Both config_set and path must 367 // match. 368 message ConfigPattern { 369 // A string pattern for config_set. 370 // 371 // If the pattern string starts with "regex:", everything after the prefix 372 // will be treated as regular expression to match the config set. The 373 // regular expression will be auto-anchored with "^" at the beginning and "$" 374 // at the end if not already. 375 // 376 // If the pattern string starts with "exact:" or "text:", everything after the 377 // prefix should be exactly the same as the config set to match the pattern. 378 // 379 // If the pattern string doesn't start with any of the above prefixes, it will 380 // be used as exact match just like "exact:" and "text:" prefixes. 381 // 382 // Note that LUCI Config will only send the service configs that belongs to 383 /// the service defined in `Service` or validation, even though the 384 // config_set pattern here can declare a much broader range (e.g. 385 // `regex:services/.+` that matches all services). 386 string config_set = 1; 387 // A string pattern for config file path. 388 // 389 // The pattern syntax is the same as `config_set` 390 string path = 2; 391 } 392 393 // Describes what configuration can be validated and how to validate them. 394 message Validator { 395 // A list of configuration patterns that this validator can validate. 396 repeated ConfigPattern patterns = 1; 397 // URL of a validation endpoint. The config service will send an HTTP POST 398 // request to the endpoint, where body is JSON-encoded 399 // ValidationRequestMessage. The endpoint is expected to respond with 400 // HTTP status 200 and JSON-encoded ValidationResponseMessage. 401 string url = 2; 402 } 403 404 // This message is used only in JSON form. It is sent as request body to an 405 // external validation endpoint in order to validate a config. 406 message ValidationRequestMessage { 407 // Config set of the config file to validate. 408 string config_set = 1; 409 // Path of the config file to validate. 410 string path = 2; 411 // Contents of the file. 412 bytes content = 3; 413 } 414 415 // This message is used only in JSON form. It is expected from an external 416 // validation endpoint that validates a config. 417 message ValidationResponseMessage { 418 // Severity of a validation response message. In JSON encoded as a string. 419 enum Severity { 420 UNKNOWN = 0; 421 DEBUG = 10; 422 INFO = 20; 423 WARNING = 30; 424 ERROR = 40; 425 CRITICAL = 50; 426 } 427 // A message that explains why a config is valid or not. 428 message Message { 429 // Path of the config file that has an error. 430 string path = 1; 431 // If an error, a config is considered invalid. Defaults to INFO. 432 Severity severity = 2; 433 // Textual representation of the message. 434 string text = 3; 435 } 436 // Errors, warnings and other information found during validation. 437 // If at least one error is found, the config is considered invalid. 438 repeated Message messages = 1; 439 } 440 441 442 /******************************************************************************/ 443 /* Service */ 444 /******************************************************************************/ 445 446 // Consumer can be implemented by the registered service that consumes config. 447 // 448 // The service should be registered in `ServicesCfg`. It is currently for a 449 // service declaring configs of interest and validate those configs. 450 service Consumer { 451 // GetMetadata returns the service metadata. 452 rpc GetMetadata(google.protobuf.Empty) returns(ServiceMetadata) {} 453 // ValidateConfigs validates the provided configs within a config set. 454 rpc ValidateConfigs(ValidateConfigsRequest) returns (ValidationResult) {}; 455 } 456 457 // ServiceMetadata describes the metadata of a service. 458 message ServiceMetadata { 459 // Patterns of config files that the service is "interested in". 460 // 461 // Interested means the service can validate config files on config files 462 // changes. 463 repeated ConfigPattern config_patterns = 1; 464 } 465 466 // ValidateConfigsRequest is the request to ValidateConfigs rpc. 467 message ValidateConfigsRequest { 468 message Files { 469 repeated File files = 1; 470 } 471 // File represents a config file to validate. 472 message File { 473 // path of the config file relative to root config directory. 474 string path = 1; 475 oneof content { 476 // RawContent is the raw byte content of the config file. 477 bytes raw_content = 2; 478 // SignedURL is a GCS singed url to download full config content. 479 // 480 // The service SHOULD provide "Accept-Encoding: gzip" header to minimize 481 // the data on the wire and the service should also be able to 482 // handle the uncompressed data based on the presence of 483 // "Content-Encoding" header. 484 // The signed url will expire shortly. Currently LUCI Config sets the 485 // expiration time to 10 min. 486 string signed_url = 3; 487 } 488 } 489 // Config set of the config files to validate. 490 string config_set = 1; 491 // Config files to validate. 492 Files files = 2; 493 } 494 495 // ValidationResult is the result of validating configs. 496 message ValidationResult { 497 // Severity of a validation response message. 498 enum Severity { 499 UNKNOWN = 0; 500 DEBUG = 10; 501 INFO = 20; 502 WARNING = 30; 503 ERROR = 40; 504 CRITICAL = 50; 505 } 506 // A message that explains why a config is valid or not. 507 message Message { 508 // Path of the config file that has an error. 509 string path = 1; 510 // If an error, a config is considered invalid. Defaults to INFO. 511 Severity severity = 2; 512 // Textual representation of the message. 513 string text = 3; 514 } 515 // Errors, warnings and other information found during validation. 516 // If at least one error is found, the config is considered invalid. 517 repeated Message messages = 1; 518 } 519