1// Copyright 2023 Google LLC 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15syntax = "proto3"; 16 17package google.cloud.resourcemanager.v3; 18 19import "google/api/annotations.proto"; 20import "google/api/client.proto"; 21import "google/api/field_behavior.proto"; 22import "google/api/resource.proto"; 23import "google/iam/v1/iam_policy.proto"; 24import "google/iam/v1/policy.proto"; 25import "google/longrunning/operations.proto"; 26import "google/protobuf/field_mask.proto"; 27import "google/protobuf/timestamp.proto"; 28 29option csharp_namespace = "Google.Cloud.ResourceManager.V3"; 30option go_package = "cloud.google.com/go/resourcemanager/apiv3/resourcemanagerpb;resourcemanagerpb"; 31option java_multiple_files = true; 32option java_outer_classname = "FoldersProto"; 33option java_package = "com.google.cloud.resourcemanager.v3"; 34option php_namespace = "Google\\Cloud\\ResourceManager\\V3"; 35option ruby_package = "Google::Cloud::ResourceManager::V3"; 36 37// Manages Cloud Platform folder resources. 38// Folders can be used to organize the resources under an 39// organization and to control the policies applied to groups of resources. 40service Folders { 41 option (google.api.default_host) = "cloudresourcemanager.googleapis.com"; 42 option (google.api.oauth_scopes) = 43 "https://www.googleapis.com/auth/cloud-platform," 44 "https://www.googleapis.com/auth/cloud-platform.read-only"; 45 46 // Retrieves a folder identified by the supplied resource name. 47 // Valid folder resource names have the format `folders/{folder_id}` 48 // (for example, `folders/1234`). 49 // The caller must have `resourcemanager.folders.get` permission on the 50 // identified folder. 51 rpc GetFolder(GetFolderRequest) returns (Folder) { 52 option (google.api.http) = { 53 get: "/v3/{name=folders/*}" 54 }; 55 option (google.api.method_signature) = "name"; 56 } 57 58 // Lists the folders that are direct descendants of supplied parent resource. 59 // `list()` provides a strongly consistent view of the folders underneath 60 // the specified parent resource. 61 // `list()` returns folders sorted based upon the (ascending) lexical ordering 62 // of their display_name. 63 // The caller must have `resourcemanager.folders.list` permission on the 64 // identified parent. 65 rpc ListFolders(ListFoldersRequest) returns (ListFoldersResponse) { 66 option (google.api.http) = { 67 get: "/v3/folders" 68 }; 69 option (google.api.method_signature) = "parent"; 70 } 71 72 // Search for folders that match specific filter criteria. 73 // `search()` provides an eventually consistent view of the folders a user has 74 // access to which meet the specified filter criteria. 75 // 76 // This will only return folders on which the caller has the 77 // permission `resourcemanager.folders.get`. 78 rpc SearchFolders(SearchFoldersRequest) returns (SearchFoldersResponse) { 79 option (google.api.http) = { 80 get: "/v3/folders:search" 81 }; 82 option (google.api.method_signature) = "query"; 83 } 84 85 // Creates a folder in the resource hierarchy. 86 // Returns an `Operation` which can be used to track the progress of the 87 // folder creation workflow. 88 // Upon success, the `Operation.response` field will be populated with the 89 // created Folder. 90 // 91 // In order to succeed, the addition of this new folder must not violate 92 // the folder naming, height, or fanout constraints. 93 // 94 // + The folder's `display_name` must be distinct from all other folders that 95 // share its parent. 96 // + The addition of the folder must not cause the active folder hierarchy 97 // to exceed a height of 10. Note, the full active + deleted folder hierarchy 98 // is allowed to reach a height of 20; this provides additional headroom when 99 // moving folders that contain deleted folders. 100 // + The addition of the folder must not cause the total number of folders 101 // under its parent to exceed 300. 102 // 103 // If the operation fails due to a folder constraint violation, some errors 104 // may be returned by the `CreateFolder` request, with status code 105 // `FAILED_PRECONDITION` and an error description. Other folder constraint 106 // violations will be communicated in the `Operation`, with the specific 107 // `PreconditionFailure` returned in the details list in the `Operation.error` 108 // field. 109 // 110 // The caller must have `resourcemanager.folders.create` permission on the 111 // identified parent. 112 rpc CreateFolder(CreateFolderRequest) returns (google.longrunning.Operation) { 113 option (google.api.http) = { 114 post: "/v3/folders" 115 body: "folder" 116 }; 117 option (google.api.method_signature) = "folder"; 118 option (google.longrunning.operation_info) = { 119 response_type: "Folder" 120 metadata_type: "CreateFolderMetadata" 121 }; 122 } 123 124 // Updates a folder, changing its `display_name`. 125 // Changes to the folder `display_name` will be rejected if they violate 126 // either the `display_name` formatting rules or the naming constraints 127 // described in the 128 // [CreateFolder][google.cloud.resourcemanager.v3.Folders.CreateFolder] 129 // documentation. 130 // 131 // The folder's `display_name` must start and end with a letter or digit, 132 // may contain letters, digits, spaces, hyphens and underscores and can be 133 // between 3 and 30 characters. This is captured by the regular expression: 134 // `[\p{L}\p{N}][\p{L}\p{N}_- ]{1,28}[\p{L}\p{N}]`. 135 // The caller must have `resourcemanager.folders.update` permission on the 136 // identified folder. 137 // 138 // If the update fails due to the unique name constraint then a 139 // `PreconditionFailure` explaining this violation will be returned 140 // in the Status.details field. 141 rpc UpdateFolder(UpdateFolderRequest) returns (google.longrunning.Operation) { 142 option (google.api.http) = { 143 patch: "/v3/{folder.name=folders/*}" 144 body: "folder" 145 }; 146 option (google.api.method_signature) = "folder,update_mask"; 147 option (google.longrunning.operation_info) = { 148 response_type: "Folder" 149 metadata_type: "UpdateFolderMetadata" 150 }; 151 } 152 153 // Moves a folder under a new resource parent. 154 // Returns an `Operation` which can be used to track the progress of the 155 // folder move workflow. 156 // Upon success, the `Operation.response` field will be populated with the 157 // moved folder. 158 // Upon failure, a `FolderOperationError` categorizing the failure cause will 159 // be returned - if the failure occurs synchronously then the 160 // `FolderOperationError` will be returned in the `Status.details` field. 161 // If it occurs asynchronously, then the FolderOperation will be returned 162 // in the `Operation.error` field. 163 // In addition, the `Operation.metadata` field will be populated with a 164 // `FolderOperation` message as an aid to stateless clients. 165 // Folder moves will be rejected if they violate either the naming, height, 166 // or fanout constraints described in the 167 // [CreateFolder][google.cloud.resourcemanager.v3.Folders.CreateFolder] 168 // documentation. The caller must have `resourcemanager.folders.move` 169 // permission on the folder's current and proposed new parent. 170 rpc MoveFolder(MoveFolderRequest) returns (google.longrunning.Operation) { 171 option (google.api.http) = { 172 post: "/v3/{name=folders/*}:move" 173 body: "*" 174 }; 175 option (google.api.method_signature) = "name,destination_parent"; 176 option (google.longrunning.operation_info) = { 177 response_type: "Folder" 178 metadata_type: "MoveFolderMetadata" 179 }; 180 } 181 182 // Requests deletion of a folder. The folder is moved into the 183 // [DELETE_REQUESTED][google.cloud.resourcemanager.v3.Folder.State.DELETE_REQUESTED] 184 // state immediately, and is deleted approximately 30 days later. This method 185 // may only be called on an empty folder, where a folder is empty if it 186 // doesn't contain any folders or projects in the 187 // [ACTIVE][google.cloud.resourcemanager.v3.Folder.State.ACTIVE] state. If 188 // called on a folder in 189 // [DELETE_REQUESTED][google.cloud.resourcemanager.v3.Folder.State.DELETE_REQUESTED] 190 // state the operation will result in a no-op success. 191 // The caller must have `resourcemanager.folders.delete` permission on the 192 // identified folder. 193 rpc DeleteFolder(DeleteFolderRequest) returns (google.longrunning.Operation) { 194 option (google.api.http) = { 195 delete: "/v3/{name=folders/*}" 196 }; 197 option (google.api.method_signature) = "name"; 198 option (google.longrunning.operation_info) = { 199 response_type: "Folder" 200 metadata_type: "DeleteFolderMetadata" 201 }; 202 } 203 204 // Cancels the deletion request for a folder. This method may be called on a 205 // folder in any state. If the folder is in the 206 // [ACTIVE][google.cloud.resourcemanager.v3.Folder.State.ACTIVE] state the 207 // result will be a no-op success. In order to succeed, the folder's parent 208 // must be in the 209 // [ACTIVE][google.cloud.resourcemanager.v3.Folder.State.ACTIVE] state. In 210 // addition, reintroducing the folder into the tree must not violate folder 211 // naming, height, and fanout constraints described in the 212 // [CreateFolder][google.cloud.resourcemanager.v3.Folders.CreateFolder] 213 // documentation. The caller must have `resourcemanager.folders.undelete` 214 // permission on the identified folder. 215 rpc UndeleteFolder(UndeleteFolderRequest) 216 returns (google.longrunning.Operation) { 217 option (google.api.http) = { 218 post: "/v3/{name=folders/*}:undelete" 219 body: "*" 220 }; 221 option (google.api.method_signature) = "name"; 222 option (google.longrunning.operation_info) = { 223 response_type: "Folder" 224 metadata_type: "UndeleteFolderMetadata" 225 }; 226 } 227 228 // Gets the access control policy for a folder. The returned policy may be 229 // empty if no such policy or resource exists. The `resource` field should 230 // be the folder's resource name, for example: "folders/1234". 231 // The caller must have `resourcemanager.folders.getIamPolicy` permission 232 // on the identified folder. 233 rpc GetIamPolicy(google.iam.v1.GetIamPolicyRequest) 234 returns (google.iam.v1.Policy) { 235 option (google.api.http) = { 236 post: "/v3/{resource=folders/*}:getIamPolicy" 237 body: "*" 238 }; 239 option (google.api.method_signature) = "resource"; 240 } 241 242 // Sets the access control policy on a folder, replacing any existing policy. 243 // The `resource` field should be the folder's resource name, for example: 244 // "folders/1234". 245 // The caller must have `resourcemanager.folders.setIamPolicy` permission 246 // on the identified folder. 247 rpc SetIamPolicy(google.iam.v1.SetIamPolicyRequest) 248 returns (google.iam.v1.Policy) { 249 option (google.api.http) = { 250 post: "/v3/{resource=folders/*}:setIamPolicy" 251 body: "*" 252 }; 253 option (google.api.method_signature) = "resource,policy"; 254 } 255 256 // Returns permissions that a caller has on the specified folder. 257 // The `resource` field should be the folder's resource name, 258 // for example: "folders/1234". 259 // 260 // There are no permissions required for making this API call. 261 rpc TestIamPermissions(google.iam.v1.TestIamPermissionsRequest) 262 returns (google.iam.v1.TestIamPermissionsResponse) { 263 option (google.api.http) = { 264 post: "/v3/{resource=folders/*}:testIamPermissions" 265 body: "*" 266 }; 267 option (google.api.method_signature) = "resource,permissions"; 268 } 269} 270 271// A folder in an organization's resource hierarchy, used to 272// organize that organization's resources. 273message Folder { 274 option (google.api.resource) = { 275 type: "cloudresourcemanager.googleapis.com/Folder" 276 pattern: "folders/{folder}" 277 style: DECLARATIVE_FRIENDLY 278 }; 279 280 // Folder lifecycle states. 281 enum State { 282 // Unspecified state. 283 STATE_UNSPECIFIED = 0; 284 285 // The normal and active state. 286 ACTIVE = 1; 287 288 // The folder has been marked for deletion by the user. 289 DELETE_REQUESTED = 2; 290 } 291 292 // Output only. The resource name of the folder. 293 // Its format is `folders/{folder_id}`, for example: "folders/1234". 294 string name = 1 [(google.api.field_behavior) = OUTPUT_ONLY]; 295 296 // Required. The folder's parent's resource name. 297 // Updates to the folder's parent must be performed using 298 // [MoveFolder][google.cloud.resourcemanager.v3.Folders.MoveFolder]. 299 string parent = 2 [(google.api.field_behavior) = REQUIRED]; 300 301 // The folder's display name. 302 // A folder's display name must be unique amongst its siblings. For example, 303 // no two folders with the same parent can share the same display name. 304 // The display name must start and end with a letter or digit, may contain 305 // letters, digits, spaces, hyphens and underscores and can be no longer 306 // than 30 characters. This is captured by the regular expression: 307 // `[\p{L}\p{N}]([\p{L}\p{N}_- ]{0,28}[\p{L}\p{N}])?`. 308 string display_name = 3; 309 310 // Output only. The lifecycle state of the folder. 311 // Updates to the state must be performed using 312 // [DeleteFolder][google.cloud.resourcemanager.v3.Folders.DeleteFolder] and 313 // [UndeleteFolder][google.cloud.resourcemanager.v3.Folders.UndeleteFolder]. 314 State state = 4 [(google.api.field_behavior) = OUTPUT_ONLY]; 315 316 // Output only. Timestamp when the folder was created. 317 google.protobuf.Timestamp create_time = 5 318 [(google.api.field_behavior) = OUTPUT_ONLY]; 319 320 // Output only. Timestamp when the folder was last modified. 321 google.protobuf.Timestamp update_time = 6 322 [(google.api.field_behavior) = OUTPUT_ONLY]; 323 324 // Output only. Timestamp when the folder was requested to be deleted. 325 google.protobuf.Timestamp delete_time = 7 326 [(google.api.field_behavior) = OUTPUT_ONLY]; 327 328 // Output only. A checksum computed by the server based on the current value 329 // of the folder resource. This may be sent on update and delete requests to 330 // ensure the client has an up-to-date value before proceeding. 331 string etag = 8 [(google.api.field_behavior) = OUTPUT_ONLY]; 332} 333 334// The GetFolder request message. 335message GetFolderRequest { 336 // Required. The resource name of the folder to retrieve. 337 // Must be of the form `folders/{folder_id}`. 338 string name = 1 [ 339 (google.api.field_behavior) = REQUIRED, 340 (google.api.resource_reference) = { 341 type: "cloudresourcemanager.googleapis.com/Folder" 342 } 343 ]; 344} 345 346// The ListFolders request message. 347message ListFoldersRequest { 348 // Required. The name of the parent resource whose folders are being listed. 349 // Only children of this parent resource are listed; descendants are not 350 // listed. 351 // 352 // If the parent is a folder, use the value `folders/{folder_id}`. If the 353 // parent is an organization, use the value `organizations/{org_id}`. 354 // 355 // Access to this method is controlled by checking the 356 // `resourcemanager.folders.list` permission on the `parent`. 357 string parent = 1 [ 358 (google.api.field_behavior) = REQUIRED, 359 (google.api.resource_reference) = { child_type: "*" } 360 ]; 361 362 // Optional. The maximum number of folders to return in the response. The 363 // server can return fewer folders than requested. If unspecified, server 364 // picks an appropriate default. 365 int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL]; 366 367 // Optional. A pagination token returned from a previous call to `ListFolders` 368 // that indicates where this listing should continue from. 369 string page_token = 3 [(google.api.field_behavior) = OPTIONAL]; 370 371 // Optional. Controls whether folders in the 372 // [DELETE_REQUESTED][google.cloud.resourcemanager.v3.Folder.State.DELETE_REQUESTED] 373 // state should be returned. Defaults to false. 374 bool show_deleted = 4 [(google.api.field_behavior) = OPTIONAL]; 375} 376 377// The ListFolders response message. 378message ListFoldersResponse { 379 // A possibly paginated list of folders that are direct descendants of 380 // the specified parent resource. 381 repeated Folder folders = 1; 382 383 // A pagination token returned from a previous call to `ListFolders` 384 // that indicates from where listing should continue. 385 string next_page_token = 2; 386} 387 388// The request message for searching folders. 389message SearchFoldersRequest { 390 // Optional. The maximum number of folders to return in the response. The 391 // server can return fewer folders than requested. If unspecified, server 392 // picks an appropriate default. 393 int32 page_size = 1 [(google.api.field_behavior) = OPTIONAL]; 394 395 // Optional. A pagination token returned from a previous call to 396 // `SearchFolders` that indicates from where search should continue. 397 string page_token = 2 [(google.api.field_behavior) = OPTIONAL]; 398 399 // Optional. Search criteria used to select the folders to return. 400 // If no search criteria is specified then all accessible folders will be 401 // returned. 402 // 403 // Query expressions can be used to restrict results based upon displayName, 404 // state and parent, where the operators `=` (`:`) `NOT`, `AND` and `OR` 405 // can be used along with the suffix wildcard symbol `*`. 406 // 407 // The `displayName` field in a query expression should use escaped quotes 408 // for values that include whitespace to prevent unexpected behavior. 409 // 410 // ``` 411 // | Field | Description | 412 // |-------------------------|----------------------------------------| 413 // | displayName | Filters by displayName. | 414 // | parent | Filters by parent (for example: folders/123). | 415 // | state, lifecycleState | Filters by state. | 416 // ``` 417 // 418 // Some example queries are: 419 // 420 // * Query `displayName=Test*` returns Folder resources whose display name 421 // starts with "Test". 422 // * Query `state=ACTIVE` returns Folder resources with 423 // `state` set to `ACTIVE`. 424 // * Query `parent=folders/123` returns Folder resources that have 425 // `folders/123` as a parent resource. 426 // * Query `parent=folders/123 AND state=ACTIVE` returns active 427 // Folder resources that have `folders/123` as a parent resource. 428 // * Query `displayName=\\"Test String\\"` returns Folder resources with 429 // display names that include both "Test" and "String". 430 string query = 3 [(google.api.field_behavior) = OPTIONAL]; 431} 432 433// The response message for searching folders. 434message SearchFoldersResponse { 435 // A possibly paginated folder search results. 436 // the specified parent resource. 437 repeated Folder folders = 1; 438 439 // A pagination token returned from a previous call to `SearchFolders` 440 // that indicates from where searching should continue. 441 string next_page_token = 2; 442} 443 444// The CreateFolder request message. 445message CreateFolderRequest { 446 // Required. The folder being created, only the display name and parent will 447 // be consulted. All other fields will be ignored. 448 Folder folder = 2 [(google.api.field_behavior) = REQUIRED]; 449} 450 451// Metadata pertaining to the Folder creation process. 452message CreateFolderMetadata { 453 // The display name of the folder. 454 string display_name = 1; 455 456 // The resource name of the folder or organization we are creating the folder 457 // under. 458 string parent = 2; 459} 460 461// The request sent to the 462// [UpdateFolder][google.cloud.resourcemanager.v3.Folder.UpdateFolder] 463// method. 464// 465// Only the `display_name` field can be changed. All other fields will be 466// ignored. Use the 467// [MoveFolder][google.cloud.resourcemanager.v3.Folders.MoveFolder] method to 468// change the `parent` field. 469message UpdateFolderRequest { 470 // Required. The new definition of the Folder. It must include the `name` 471 // field, which cannot be changed. 472 Folder folder = 1 [(google.api.field_behavior) = REQUIRED]; 473 474 // Required. Fields to be updated. 475 // Only the `display_name` can be updated. 476 google.protobuf.FieldMask update_mask = 2 477 [(google.api.field_behavior) = REQUIRED]; 478} 479 480// A status object which is used as the `metadata` field for the Operation 481// returned by UpdateFolder. 482message UpdateFolderMetadata {} 483 484// The MoveFolder request message. 485message MoveFolderRequest { 486 // Required. The resource name of the Folder to move. 487 // Must be of the form folders/{folder_id} 488 string name = 1 [ 489 (google.api.field_behavior) = REQUIRED, 490 (google.api.resource_reference) = { 491 type: "cloudresourcemanager.googleapis.com/Folder" 492 } 493 ]; 494 495 // Required. The resource name of the folder or organization which should be 496 // the folder's new parent. Must be of the form `folders/{folder_id}` or 497 // `organizations/{org_id}`. 498 string destination_parent = 2 [ 499 (google.api.field_behavior) = REQUIRED, 500 (google.api.resource_reference) = { child_type: "*" } 501 ]; 502} 503 504// Metadata pertaining to the folder move process. 505message MoveFolderMetadata { 506 // The display name of the folder. 507 string display_name = 1; 508 509 // The resource name of the folder's parent. 510 string source_parent = 2; 511 512 // The resource name of the folder or organization to move the folder to. 513 string destination_parent = 3; 514} 515 516// The DeleteFolder request message. 517message DeleteFolderRequest { 518 // Required. The resource name of the folder to be deleted. 519 // Must be of the form `folders/{folder_id}`. 520 string name = 1 [ 521 (google.api.field_behavior) = REQUIRED, 522 (google.api.resource_reference) = { 523 type: "cloudresourcemanager.googleapis.com/Folder" 524 } 525 ]; 526} 527 528// A status object which is used as the `metadata` field for the `Operation` 529// returned by `DeleteFolder`. 530message DeleteFolderMetadata {} 531 532// The UndeleteFolder request message. 533message UndeleteFolderRequest { 534 // Required. The resource name of the folder to undelete. 535 // Must be of the form `folders/{folder_id}`. 536 string name = 1 [ 537 (google.api.field_behavior) = REQUIRED, 538 (google.api.resource_reference) = { 539 type: "cloudresourcemanager.googleapis.com/Folder" 540 } 541 ]; 542} 543 544// A status object which is used as the `metadata` field for the `Operation` 545// returned by `UndeleteFolder`. 546message UndeleteFolderMetadata {} 547