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