From a4cc7cd979102f3371e51a499a577f67caf8218a Mon Sep 17 00:00:00 2001 From: Ludovico Magnocavallo Date: Tue, 21 Oct 2025 14:03:40 +0200 Subject: [PATCH] Align schemas (#3447) * enforce schema uniqueness * schemas * fix tests --- .../0-org-setup/schemas/folder.schema.json | 556 ++++++++- .../0-org-setup/schemas/folder.schema.md | 189 ++- .../0-org-setup/schemas/project.schema.json | 1009 ++++++++++++++++- .../0-org-setup/schemas/project.schema.md | 311 ++++- .../1-vpcsc/schemas/perimeter.schema.json | 121 +- .../2-security/schemas/project.schema.json | 216 +++- modules/organization/schemas/tags.schema.json | 6 +- modules/organization/schemas/tags.schema.md | 6 +- modules/vpc-sc/README.md | 4 +- ...ters.schema.json => perimeter.schema.json} | 0 tools/duplicate-diff.py | 90 +- 11 files changed, 2492 insertions(+), 16 deletions(-) mode change 120000 => 100644 fast/stages/0-org-setup/schemas/folder.schema.json mode change 120000 => 100644 fast/stages/0-org-setup/schemas/folder.schema.md mode change 120000 => 100644 fast/stages/0-org-setup/schemas/project.schema.json mode change 120000 => 100644 fast/stages/0-org-setup/schemas/project.schema.md mode change 120000 => 100644 fast/stages/1-vpcsc/schemas/perimeter.schema.json rename modules/vpc-sc/schemas/{perimeters.schema.json => perimeter.schema.json} (100%) diff --git a/fast/stages/0-org-setup/schemas/folder.schema.json b/fast/stages/0-org-setup/schemas/folder.schema.json deleted file mode 120000 index d58a2759b..000000000 --- a/fast/stages/0-org-setup/schemas/folder.schema.json +++ /dev/null @@ -1 +0,0 @@ -../../../../modules/project-factory/schemas/folder.schema.json \ No newline at end of file diff --git a/fast/stages/0-org-setup/schemas/folder.schema.json b/fast/stages/0-org-setup/schemas/folder.schema.json new file mode 100644 index 000000000..778dc0572 --- /dev/null +++ b/fast/stages/0-org-setup/schemas/folder.schema.json @@ -0,0 +1,555 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Folder", + "type": "object", + "additionalProperties": false, + "properties": { + "automation": { + "type": "object", + "additionalProperties": false, + "required": [ + "project" + ], + "properties": { + "prefix": { + "type": "string" + }, + "project": { + "type": "string" + }, + "bucket": { + "$ref": "#/$defs/bucket" + }, + "service_accounts": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9-]+$": { + "type": "object", + "additionalProperties": false, + "properties": { + "description": { + "type": "string" + }, + "iam": { + "$ref": "#/$defs/iam" + }, + "iam_bindings": { + "$ref": "#/$defs/iam_bindings" + }, + "iam_bindings_additive": { + "$ref": "#/$defs/iam_bindings_additive" + }, + "iam_billing_roles": { + "$ref": "#/$defs/iam_billing_roles" + }, + "iam_folder_roles": { + "$ref": "#/$defs/iam_folder_roles" + }, + "iam_organization_roles": { + "$ref": "#/$defs/iam_organization_roles" + }, + "iam_project_roles": { + "$ref": "#/$defs/iam_project_roles" + }, + "iam_sa_roles": { + "$ref": "#/$defs/iam_sa_roles" + }, + "iam_storage_roles": { + "$ref": "#/$defs/iam_storage_roles" + } + } + } + } + } + } + }, + "factories_config": { + "type": "object", + "additionalProperties": false, + "properties": { + "org_policies": { + "type": "string" + }, + "pam_entitlements": { + "type": "string" + }, + "scc_sha_custom_modules": { + "type": "string" + } + } + }, + "iam": { + "$ref": "#/$defs/iam" + }, + "iam_bindings": { + "$ref": "#/$defs/iam_bindings" + }, + "iam_bindings_additive": { + "$ref": "#/$defs/iam_bindings_additive" + }, + "iam_by_principals": { + "$ref": "#/$defs/iam_by_principals" + }, + "name": { + "type": "string" + }, + "org_policies": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z]+\\.": { + "type": "object", + "properties": { + "inherit_from_parent": { + "type": "boolean" + }, + "reset": { + "type": "boolean" + }, + "rules": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "properties": { + "allow": { + "type": "object", + "additionalProperties": false, + "properties": { + "all": { + "type": "boolean" + }, + "values": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "deny": { + "type": "object", + "additionalProperties": false, + "properties": { + "all": { + "type": "boolean" + }, + "values": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "enforce": { + "type": "boolean" + }, + "condition": { + "type": "object", + "additionalProperties": false, + "properties": { + "description": { + "type": "string" + }, + "expression": { + "type": "string" + }, + "location": { + "type": "string" + }, + "title": { + "type": "string" + } + } + } + } + } + } + } + } + } + }, + "pam_entitlements": { + "$ref": "#/$defs/pam_entitlements" + }, + "parent": { + "type": "string", + "pattern": "^(?:folders/[0-9]+|organizations/[0-9]+|\\$folder_ids:[a-z0-9_-]+)$" + }, + "tag_bindings": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9_-]+$": { + "type": "string" + } + } + } + }, + "$defs": { + "bucket": { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "iam": { + "$ref": "#/$defs/iam" + }, + "iam_bindings": { + "$ref": "#/$defs/iam_bindings" + }, + "iam_bindings_additive": { + "$ref": "#/$defs/iam_bindings_additive" + }, + "force_destroy": { + "type": "boolean" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "location": { + "type": "string" + }, + "managed_folders": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-zA-Z0-9][a-zA-Z0-9_/-]+$": { + "type": "object", + "additionalProperties": false, + "properties": { + "force_destroy": { + "type": "boolean" + }, + "iam": { + "$ref": "#/$defs/iam" + }, + "iam_bindings": { + "$ref": "#/$defs/iam_bindings" + }, + "iam_bindings_additive": { + "$ref": "#/$defs/iam_bindings_additive" + } + } + } + } + }, + "prefix": { + "type": "string" + }, + "storage_class": { + "type": "string" + }, + "uniform_bucket_level_access": { + "type": "boolean" + }, + "versioning": { + "type": "boolean" + } + } + }, + "iam": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^(?:roles/|\\$custom_roles:)": { + "type": "array", + "items": { + "type": "string", + "pattern": "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\\$iam_principals:)" + } + } + } + }, + "iam_bindings": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9_-]+$": { + "type": "object", + "additionalProperties": false, + "properties": { + "members": { + "type": "array", + "items": { + "type": "string", + "pattern": "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\\$iam_principals:)" + } + }, + "role": { + "type": "string", + "pattern": "^(?:roles/|\\$custom_roles:)" + }, + "condition": { + "type": "object", + "additionalProperties": false, + "required": [ + "expression", + "title" + ], + "properties": { + "expression": { + "type": "string" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + } + } + } + } + } + } + }, + "iam_bindings_additive": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9_-]+$": { + "type": "object", + "additionalProperties": false, + "properties": { + "member": { + "type": "string", + "pattern": "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\\$iam_principals:)" + }, + "role": { + "type": "string", + "pattern": "^(?:roles/|\\$custom_roles:)" + }, + "condition": { + "type": "object", + "additionalProperties": false, + "required": [ + "expression", + "title" + ], + "properties": { + "expression": { + "type": "string" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + } + } + } + } + } + } + }, + "iam_by_principals": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\\$iam_principals:)": { + "type": "array", + "items": { + "type": "string", + "pattern": "^(?:roles/|\\$custom_roles:)" + } + } + } + }, + "iam_billing_roles": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9-]+$": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "iam_folder_roles": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9-]+$": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "iam_organization_roles": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9-]+$": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "iam_project_roles": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9-]+$": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "iam_sa_roles": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9-]+$": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "iam_storage_roles": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9-]+$": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "pam_entitlements": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z][a-z0-9-]{0,61}[a-z0-9]$": { + "type": "object", + "properties": { + "max_request_duration": { + "type": "string" + }, + "eligible_users": { + "type": "array", + "items": { + "type": "string" + } + }, + "privileged_access": { + "type": "array", + "items": { + "type": "object", + "properties": { + "role": { + "type": "string" + }, + "condition": { + "type": "string" + } + }, + "required": [ + "role" + ], + "additionalProperties": false + } + }, + "requester_justification_config": { + "type": "object", + "properties": { + "not_mandatory": { + "type": "boolean" + }, + "unstructured": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "manual_approvals": { + "type": "object", + "properties": { + "require_approver_justification": { + "type": "boolean" + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "properties": { + "approvers": { + "type": "array", + "items": { + "type": "string" + } + }, + "approvals_needed": { + "type": "number" + }, + "approver_email_recipients": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "approvers" + ], + "additionalProperties": false + } + } + }, + "required": [ + "require_approver_justification", + "steps" + ], + "additionalProperties": false + }, + "additional_notification_targets": { + "type": "object", + "properties": { + "admin_email_recipients": { + "type": "array", + "items": { + "type": "string" + } + }, + "requester_email_recipients": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + } + }, + "required": [ + "max_request_duration", + "eligible_users", + "privileged_access" + ], + "additionalProperties": false + } + } + } + } +} diff --git a/fast/stages/0-org-setup/schemas/folder.schema.md b/fast/stages/0-org-setup/schemas/folder.schema.md deleted file mode 120000 index acf5b4bda..000000000 --- a/fast/stages/0-org-setup/schemas/folder.schema.md +++ /dev/null @@ -1 +0,0 @@ -../../../../modules/project-factory/schemas/folder.schema.md \ No newline at end of file diff --git a/fast/stages/0-org-setup/schemas/folder.schema.md b/fast/stages/0-org-setup/schemas/folder.schema.md new file mode 100644 index 000000000..fe5ae2511 --- /dev/null +++ b/fast/stages/0-org-setup/schemas/folder.schema.md @@ -0,0 +1,188 @@ +# Folder + + + +## Properties + +*additional properties: false* + +- **automation**: *object* +
*additional properties: false* + - **prefix**: *string* + - ⁺**project**: *string* + - **bucket**: *reference([bucket](#refs-bucket))* + - **service_accounts**: *object* +
*additional properties: false* + - **`^[a-z0-9-]+$`**: *object* +
*additional properties: false* + - **description**: *string* + - **iam**: *reference([iam](#refs-iam))* + - **iam_bindings**: *reference([iam_bindings](#refs-iam_bindings))* + - **iam_bindings_additive**: *reference([iam_bindings_additive](#refs-iam_bindings_additive))* + - **iam_billing_roles**: *reference([iam_billing_roles](#refs-iam_billing_roles))* + - **iam_folder_roles**: *reference([iam_folder_roles](#refs-iam_folder_roles))* + - **iam_organization_roles**: *reference([iam_organization_roles](#refs-iam_organization_roles))* + - **iam_project_roles**: *reference([iam_project_roles](#refs-iam_project_roles))* + - **iam_sa_roles**: *reference([iam_sa_roles](#refs-iam_sa_roles))* + - **iam_storage_roles**: *reference([iam_storage_roles](#refs-iam_storage_roles))* +- **factories_config**: *object* +
*additional properties: false* + - **org_policies**: *string* + - **pam_entitlements**: *string* + - **scc_sha_custom_modules**: *string* +- **iam**: *reference([iam](#refs-iam))* +- **iam_bindings**: *reference([iam_bindings](#refs-iam_bindings))* +- **iam_bindings_additive**: *reference([iam_bindings_additive](#refs-iam_bindings_additive))* +- **iam_by_principals**: *reference([iam_by_principals](#refs-iam_by_principals))* +- **name**: *string* +- **org_policies**: *object* +
*additional properties: false* + - **`^[a-z]+\.`**: *object* + - **inherit_from_parent**: *boolean* + - **reset**: *boolean* + - **rules**: *array* + - items: *object* +
*additional properties: false* + - **allow**: *object* +
*additional properties: false* + - **all**: *boolean* + - **values**: *array* + - items: *string* + - **deny**: *object* +
*additional properties: false* + - **all**: *boolean* + - **values**: *array* + - items: *string* + - **enforce**: *boolean* + - **condition**: *object* +
*additional properties: false* + - **description**: *string* + - **expression**: *string* + - **location**: *string* + - **title**: *string* +- **pam_entitlements**: *reference([pam_entitlements](#refs-pam_entitlements))* +- **parent**: *string* +
*pattern: ^(?:folders/[0-9]+|organizations/[0-9]+|\$folder_ids:[a-z0-9_-]+)$* +- **tag_bindings**: *object* +
*additional properties: false* + - **`^[a-z0-9_-]+$`**: *string* + +## Definitions + +- **bucket**: *object* +
*additional properties: false* + - **name**: *string* + - **description**: *string* + - **iam**: *reference([iam](#refs-iam))* + - **iam_bindings**: *reference([iam_bindings](#refs-iam_bindings))* + - **iam_bindings_additive**: *reference([iam_bindings_additive](#refs-iam_bindings_additive))* + - **force_destroy**: *boolean* + - **labels**: *object* + *additional properties: String* + - **location**: *string* + - **managed_folders**: *object* +
*additional properties: false* + - **`^[a-zA-Z0-9][a-zA-Z0-9_/-]+$`**: *object* +
*additional properties: false* + - **force_destroy**: *boolean* + - **iam**: *reference([iam](#refs-iam))* + - **iam_bindings**: *reference([iam_bindings](#refs-iam_bindings))* + - **iam_bindings_additive**: *reference([iam_bindings_additive](#refs-iam_bindings_additive))* + - **prefix**: *string* + - **storage_class**: *string* + - **uniform_bucket_level_access**: *boolean* + - **versioning**: *boolean* +- **iam**: *object* +
*additional properties: false* + - **`^(?:roles/|\$custom_roles:)`**: *array* + - items: *string* +
*pattern: ^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\$iam_principals:)* +- **iam_bindings**: *object* +
*additional properties: false* + - **`^[a-z0-9_-]+$`**: *object* +
*additional properties: false* + - **members**: *array* + - items: *string* +
*pattern: ^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\$iam_principals:)* + - **role**: *string* +
*pattern: ^(?:roles/|\$custom_roles:)* + - **condition**: *object* +
*additional properties: false* + - ⁺**expression**: *string* + - ⁺**title**: *string* + - **description**: *string* +- **iam_bindings_additive**: *object* +
*additional properties: false* + - **`^[a-z0-9_-]+$`**: *object* +
*additional properties: false* + - **member**: *string* +
*pattern: ^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\$iam_principals:)* + - **role**: *string* +
*pattern: ^(?:roles/|\$custom_roles:)* + - **condition**: *object* +
*additional properties: false* + - ⁺**expression**: *string* + - ⁺**title**: *string* + - **description**: *string* +- **iam_by_principals**: *object* +
*additional properties: false* + - **`^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\$iam_principals:)`**: *array* + - items: *string* +
*pattern: ^(?:roles/|\$custom_roles:)* +- **iam_billing_roles**: *object* +
*additional properties: false* + - **`^[a-z0-9-]+$`**: *array* + - items: *string* +- **iam_folder_roles**: *object* +
*additional properties: false* + - **`^[a-z0-9-]+$`**: *array* + - items: *string* +- **iam_organization_roles**: *object* +
*additional properties: false* + - **`^[a-z0-9-]+$`**: *array* + - items: *string* +- **iam_project_roles**: *object* +
*additional properties: false* + - **`^[a-z0-9-]+$`**: *array* + - items: *string* +- **iam_sa_roles**: *object* +
*additional properties: false* + - **`^[a-z0-9-]+$`**: *array* + - items: *string* +- **iam_storage_roles**: *object* +
*additional properties: false* + - **`^[a-z0-9-]+$`**: *array* + - items: *string* +- **pam_entitlements**: *object* +
*additional properties: false* + - **`^[a-z][a-z0-9-]{0,61}[a-z0-9]$`**: *object* +
*additional properties: false* + - ⁺**max_request_duration**: *string* + - ⁺**eligible_users**: *array* + - items: *string* + - ⁺**privileged_access**: *array* + - items: *object* +
*additional properties: false* + - ⁺**role**: *string* + - **condition**: *string* + - **requester_justification_config**: *object* +
*additional properties: false* + - **not_mandatory**: *boolean* + - **unstructured**: *boolean* + - **manual_approvals**: *object* +
*additional properties: false* + - ⁺**require_approver_justification**: *boolean* + - ⁺**steps**: *array* + - items: *object* +
*additional properties: false* + - ⁺**approvers**: *array* + - items: *string* + - **approvals_needed**: *number* + - **approver_email_recipients**: *array* + - items: *string* + - **additional_notification_targets**: *object* +
*additional properties: false* + - **admin_email_recipients**: *array* + - items: *string* + - **requester_email_recipients**: *array* + - items: *string* diff --git a/fast/stages/0-org-setup/schemas/project.schema.json b/fast/stages/0-org-setup/schemas/project.schema.json deleted file mode 120000 index 11f161f17..000000000 --- a/fast/stages/0-org-setup/schemas/project.schema.json +++ /dev/null @@ -1 +0,0 @@ -../../../../modules/project-factory/schemas/project.schema.json \ No newline at end of file diff --git a/fast/stages/0-org-setup/schemas/project.schema.json b/fast/stages/0-org-setup/schemas/project.schema.json new file mode 100644 index 000000000..228c10c06 --- /dev/null +++ b/fast/stages/0-org-setup/schemas/project.schema.json @@ -0,0 +1,1008 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Project", + "type": "object", + "additionalProperties": false, + "properties": { + "automation": { + "type": "object", + "additionalProperties": false, + "required": [ + "project" + ], + "properties": { + "prefix": { + "type": "string" + }, + "project": { + "type": "string" + }, + "bucket": { + "$ref": "#/$defs/bucket" + }, + "service_accounts": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9-]+$": { + "type": "object", + "additionalProperties": false, + "properties": { + "description": { + "type": "string" + }, + "iam": { + "$ref": "#/$defs/iam" + }, + "iam_bindings": { + "$ref": "#/$defs/iam_bindings" + }, + "iam_bindings_additive": { + "$ref": "#/$defs/iam_bindings_additive" + }, + "iam_billing_roles": { + "$ref": "#/$defs/iam_billing_roles" + }, + "iam_folder_roles": { + "$ref": "#/$defs/iam_folder_roles" + }, + "iam_organization_roles": { + "$ref": "#/$defs/iam_organization_roles" + }, + "iam_project_roles": { + "$ref": "#/$defs/iam_project_roles" + }, + "iam_sa_roles": { + "$ref": "#/$defs/iam_sa_roles" + }, + "iam_storage_roles": { + "$ref": "#/$defs/iam_storage_roles" + } + } + } + } + } + } + }, + "billing_account": { + "type": "string" + }, + "billing_budgets": { + "type": "array", + "items": { + "type": "string" + } + }, + "buckets": { + "$ref": "#/$defs/buckets" + }, + "contacts": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9_-]+$": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "datasets": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9_]+$": { + "type": "object", + "additionalProperties": false, + "properties": { + "friendly_name": { + "type": "string" + }, + "location": { + "type": "string" + } + } + } + } + }, + "deletion_policy": { + "type": "string", + "enum": [ + "PREVENT", + "DELETE", + "ABANDON" + ] + }, + "factories_config": { + "type": "object", + "additionalProperties": false, + "properties": { + "custom_roles": { + "type": "string" + }, + "observability": { + "type": "string" + }, + "org_policies": { + "type": "string" + }, + "org_policies": { + "type": "string" + }, + "quotas": { + "type": "string" + }, + "scc_sha_custom_modules": { + "type": "string" + }, + "tags": { + "type": "string" + } + } + }, + "iam": { + "$ref": "#/$defs/iam" + }, + "iam_bindings": { + "$ref": "#/$defs/iam_bindings" + }, + "iam_bindings_additive": { + "$ref": "#/$defs/iam_bindings_additive" + }, + "iam_by_principals": { + "$ref": "#/$defs/iam_by_principals" + }, + "iam_by_principals_additive": { + "$ref": "#/$defs/iam_by_principals" + }, + "labels": { + "type": "object" + }, + "pam_entitlements": { + "$ref": "#/$defs/pam_entitlements" + }, + "log_buckets": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9-]+$": { + "$ref": "#/$defs/log_bucket" + } + } + }, + "metric_scopes": { + "type": "array", + "items": { + "type": "string" + } + }, + "name": { + "type": "string" + }, + "org_policies": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z]+\\.": { + "type": "object", + "properties": { + "inherit_from_parent": { + "type": "boolean" + }, + "reset": { + "type": "boolean" + }, + "rules": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "properties": { + "allow": { + "type": "object", + "additionalProperties": false, + "properties": { + "all": { + "type": "boolean" + }, + "values": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "deny": { + "type": "object", + "additionalProperties": false, + "properties": { + "all": { + "type": "boolean" + }, + "values": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "enforce": { + "type": "boolean" + }, + "condition": { + "type": "object", + "additionalProperties": false, + "properties": { + "description": { + "type": "string" + }, + "expression": { + "type": "string" + }, + "location": { + "type": "string" + }, + "title": { + "type": "string" + } + } + } + } + } + } + } + } + } + }, + "quotas": { + "title": "Quotas", + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-zA-Z0-9_-]+$": { + "type": "object", + "additionalProperties": false, + "required": [ + "service", + "quota_id", + "preferred_value" + ], + "properties": { + "service": { + "type": "string" + }, + "quota_id": { + "type": "string" + }, + "preferred_value": { + "type": "number" + }, + "dimensions": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "justification": { + "type": "string" + }, + "contact_email": { + "type": "string" + }, + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "ignore_safety_checks": { + "type": "string", + "enum": [ + "QUOTA_DECREASE_BELOW_USAGE", + "QUOTA_DECREASE_PERCENTAGE_TOO_HIGH", + "QUOTA_SAFETY_CHECK_UNSPECIFIED" + ] + } + } + } + } + }, + "parent": { + "type": "string" + }, + "prefix": { + "type": "string" + }, + "project_reuse": { + "type": "object", + "additionalProperties": false, + "properties": { + "use_data_source": { + "type": "boolean" + }, + "attributes": { + "type": "object", + "required": [ + "name", + "number" + ], + "properties": { + "name": { + "type": "string" + }, + "number": { + "type": "number" + }, + "services_enabled": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + }, + "project_template": { + "type": "string" + }, + "service_accounts": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9-]+$": { + "type": "object", + "additionalProperties": false, + "properties": { + "display_name": { + "type": "string" + }, + "iam": { + "$ref": "#/$defs/iam" + }, + "iam_self_roles": { + "type": "array", + "items": { + "type": "string" + } + }, + "iam_project_roles": { + "$ref": "#/$defs/iam_project_roles" + }, + "iam_sa_roles": { + "$ref": "#/$defs/iam_sa_roles" + } + } + } + } + }, + "service_encryption_key_ids": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z-]+\\.googleapis\\.com$": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "services": { + "type": "array", + "items": { + "type": "string", + "pattern": "^[a-z-]+\\.googleapis\\.com$" + } + }, + "shared_vpc_host_config": { + "type": "object", + "additionalProperties": false, + "required": [ + "enabled" + ], + "properties": { + "enabled": { + "type": "boolean" + }, + "service_projects": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "shared_vpc_service_config": { + "type": "object", + "additionalProperties": false, + "required": [ + "host_project" + ], + "properties": { + "host_project": { + "type": "string" + }, + "iam_bindings_additive": { + "$ref": "#/$defs/iam_bindings_additive" + }, + "network_users": { + "type": "array", + "items": { + "type": "string" + } + }, + "service_agent_iam": { + "type": "object", + "additionalItems": false, + "patternProperties": { + "^[a-z0-9_-]+$": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "service_agent_subnet_iam": { + "type": "object", + "additionalItems": false, + "patternProperties": { + "^[a-z0-9_-]+$": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "service_iam_grants": { + "type": "array", + "items": { + "type": "string" + } + }, + "network_subnet_users": { + "type": "object", + "additionalItems": false, + "patternProperties": { + "^[a-z0-9_-]+$": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + }, + "tag_bindings": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9_-]+$": { + "type": "string" + } + } + }, + "tags": { + "type": "object", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "properties": { + "description": { + "type": "string" + }, + "iam": { + "$ref": "#/$defs/iam" + }, + "iam_bindings": { + "$ref": "#/$defs/iam_bindings" + }, + "iam_bindings_additive": { + "$ref": "#/$defs/iam_bindings_additive" + }, + "id": { + "type": "string" + }, + "values": { + "type": "object", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "properties": { + "description": { + "type": "string" + }, + "iam": { + "$ref": "#/$defs/iam" + }, + "iam_bindings": { + "$ref": "#/$defs/iam_bindings" + }, + "iam_bindings_additive": { + "$ref": "#/$defs/iam_bindings_additive" + }, + "id": { + "type": "string" + } + } + } + } + } + } + }, + "universe": { + "type": "object", + "additionalProperties": false, + "properties": { + "prefix": { + "type": "string" + }, + "forced_jit_service_identities": { + "type": "array", + "items": { + "type": "string" + } + }, + "unavailable_services": { + "type": "array", + "items": { + "type": "string" + } + }, + "unavailable_service_identities": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "vpc_sc": { + "type": "object", + "additionalItems": false, + "required": [ + "perimeter_name" + ], + "properties": { + "perimeter_name": { + "type": "string" + }, + "is_dry_run": { + "type": "boolean" + } + } + } + }, + "$defs": { + "bucket": { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "create": { + "type": "boolean", + "default": true + }, + "description": { + "type": "string" + }, + "iam": { + "$ref": "#/$defs/iam" + }, + "iam_bindings": { + "$ref": "#/$defs/iam_bindings" + }, + "iam_bindings_additive": { + "$ref": "#/$defs/iam_bindings_additive" + }, + "force_destroy": { + "type": "boolean" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "location": { + "type": "string" + }, + "managed_folders": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-zA-Z0-9][a-zA-Z0-9_/-]+$": { + "type": "object", + "additionalProperties": false, + "properties": { + "force_destroy": { + "type": "boolean" + }, + "iam": { + "$ref": "#/$defs/iam" + }, + "iam_bindings": { + "$ref": "#/$defs/iam_bindings" + }, + "iam_bindings_additive": { + "$ref": "#/$defs/iam_bindings_additive" + } + } + } + } + }, + "prefix": { + "type": "string" + }, + "storage_class": { + "type": "string" + }, + "uniform_bucket_level_access": { + "type": "boolean" + }, + "versioning": { + "type": "boolean" + }, + "retention_policy": { + "type": "object", + "additionalProperties": false, + "properties": { + "retention_period": { + "type": "number" + }, + "is_locked": { + "type": "boolean" + } + } + }, + "enable_object_retention": { + "type": "boolean" + } + } + }, + "buckets": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9-]+$": { + "$ref": "#/$defs/bucket" + } + } + }, + "iam": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^(?:roles/|\\$custom_roles:)": { + "type": "array", + "items": { + "type": "string", + "pattern": "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:||\\$iam_principals:[a-z0-9_-]+)" + } + } + } + }, + "iam_bindings": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9_-]+$": { + "type": "object", + "additionalProperties": false, + "properties": { + "members": { + "type": "array", + "items": { + "type": "string", + "pattern": "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\\$iam_principals:[a-z0-9_-]+)" + } + }, + "role": { + "type": "string", + "pattern": "^(?:roles/|\\$custom_roles:)" + }, + "condition": { + "type": "object", + "additionalProperties": false, + "required": [ + "expression", + "title" + ], + "properties": { + "expression": { + "type": "string" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + } + } + } + } + } + } + }, + "iam_bindings_additive": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9_-]+$": { + "type": "object", + "additionalProperties": false, + "properties": { + "member": { + "type": "string", + "pattern": "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\\$iam_principals:[a-z0-9_-]+)" + }, + "role": { + "type": "string", + "pattern": "^(?:roles/|\\$custom_roles:)" + }, + "condition": { + "type": "object", + "additionalProperties": false, + "required": [ + "expression", + "title" + ], + "properties": { + "expression": { + "type": "string" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + } + } + } + } + } + } + }, + "iam_by_principals": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\\$iam_principals:[a-z0-9_-]+)": { + "type": "array", + "items": { + "type": "string", + "pattern": "^(?:roles/|\\$custom_roles:)" + } + } + } + }, + "iam_billing_roles": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9-]+$": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "iam_folder_roles": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9-]+$": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "iam_organization_roles": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9-]+$": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "iam_project_roles": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^(?:[a-z0-9-]|\\$project_ids:[a-z0-9_-])+$": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "iam_sa_roles": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^(?:\\$service_account_ids:|projects/)": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "iam_storage_roles": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9-]+$": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "log_bucket": { + "type": "object", + "additionalProperties": false, + "properties": { + "description": { + "type": "string" + }, + "kms_key_name": { + "type": "string" + }, + "location": { + "type": "string" + }, + "log_analytics": { + "type": "object", + "additionalProperties": false, + "properties": { + "enable": { + "type": "boolean", + "default": false + }, + "dataset_link_id": { + "type": "string" + }, + "description": { + "type": "string" + } + } + }, + "retention": { + "type": "number" + } + } + }, + "pam_entitlements": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z][a-z0-9-]{0,61}[a-z0-9]$": { + "type": "object", + "properties": { + "max_request_duration": { + "type": "string" + }, + "eligible_users": { + "type": "array", + "items": { + "type": "string" + } + }, + "privileged_access": { + "type": "array", + "items": { + "type": "object", + "properties": { + "role": { + "type": "string" + }, + "condition": { + "type": "string" + } + }, + "required": [ + "role" + ], + "additionalProperties": false + } + }, + "requester_justification_config": { + "type": "object", + "properties": { + "not_mandatory": { + "type": "boolean" + }, + "unstructured": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "manual_approvals": { + "type": "object", + "properties": { + "require_approver_justification": { + "type": "boolean" + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "properties": { + "approvers": { + "type": "array", + "items": { + "type": "string" + } + }, + "approvals_needed": { + "type": "number" + }, + "approver_email_recipients": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "approvers" + ], + "additionalProperties": false + } + } + }, + "required": [ + "require_approver_justification", + "steps" + ], + "additionalProperties": false + }, + "additional_notification_targets": { + "type": "object", + "properties": { + "admin_email_recipients": { + "type": "array", + "items": { + "type": "string" + } + }, + "requester_email_recipients": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + } + }, + "required": [ + "max_request_duration", + "eligible_users", + "privileged_access" + ], + "additionalProperties": false + } + } + } + } +} diff --git a/fast/stages/0-org-setup/schemas/project.schema.md b/fast/stages/0-org-setup/schemas/project.schema.md deleted file mode 120000 index 1b04336aa..000000000 --- a/fast/stages/0-org-setup/schemas/project.schema.md +++ /dev/null @@ -1 +0,0 @@ -../../../../modules/project-factory/schemas/project.schema.md \ No newline at end of file diff --git a/fast/stages/0-org-setup/schemas/project.schema.md b/fast/stages/0-org-setup/schemas/project.schema.md new file mode 100644 index 000000000..2394111b4 --- /dev/null +++ b/fast/stages/0-org-setup/schemas/project.schema.md @@ -0,0 +1,310 @@ +# Project + + + +## Properties + +*additional properties: false* + +- **automation**: *object* +
*additional properties: false* + - **prefix**: *string* + - ⁺**project**: *string* + - **bucket**: *reference([bucket](#refs-bucket))* + - **service_accounts**: *object* +
*additional properties: false* + - **`^[a-z0-9-]+$`**: *object* +
*additional properties: false* + - **description**: *string* + - **iam**: *reference([iam](#refs-iam))* + - **iam_bindings**: *reference([iam_bindings](#refs-iam_bindings))* + - **iam_bindings_additive**: *reference([iam_bindings_additive](#refs-iam_bindings_additive))* + - **iam_billing_roles**: *reference([iam_billing_roles](#refs-iam_billing_roles))* + - **iam_folder_roles**: *reference([iam_folder_roles](#refs-iam_folder_roles))* + - **iam_organization_roles**: *reference([iam_organization_roles](#refs-iam_organization_roles))* + - **iam_project_roles**: *reference([iam_project_roles](#refs-iam_project_roles))* + - **iam_sa_roles**: *reference([iam_sa_roles](#refs-iam_sa_roles))* + - **iam_storage_roles**: *reference([iam_storage_roles](#refs-iam_storage_roles))* +- **billing_account**: *string* +- **billing_budgets**: *array* + - items: *string* +- **buckets**: *reference([buckets](#refs-buckets))* +- **contacts**: *object* +
*additional properties: false* + - **`^[a-z0-9_-]+$`**: *array* + - items: *string* +- **deletion_policy**: *string* +
*enum: ['PREVENT', 'DELETE', 'ABANDON']* +- **factories_config**: *object* +
*additional properties: false* + - **custom_roles**: *string* + - **observability**: *string* + - **org_policies**: *string* + - **quotas**: *string* + - **scc_sha_custom_modules**: *string* + - **tags**: *string* +- **iam**: *reference([iam](#refs-iam))* +- **iam_bindings**: *reference([iam_bindings](#refs-iam_bindings))* +- **iam_bindings_additive**: *reference([iam_bindings_additive](#refs-iam_bindings_additive))* +- **iam_by_principals**: *reference([iam_by_principals](#refs-iam_by_principals))* +- **labels**: *object* +- **pam_entitlements**: *reference([pam_entitlements](#refs-pam_entitlements))* +- **log_buckets**: *object* +
*additional properties: false* + - **`^[a-z0-9-]+$`**: *reference([log_bucket](#refs-log_bucket))* +- **metric_scopes**: *array* + - items: *string* +- **name**: *string* +- **org_policies**: *object* +
*additional properties: false* + - **`^[a-z]+\.`**: *object* + - **inherit_from_parent**: *boolean* + - **reset**: *boolean* + - **rules**: *array* + - items: *object* +
*additional properties: false* + - **allow**: *object* +
*additional properties: false* + - **all**: *boolean* + - **values**: *array* + - items: *string* + - **deny**: *object* +
*additional properties: false* + - **all**: *boolean* + - **values**: *array* + - items: *string* + - **enforce**: *boolean* + - **condition**: *object* +
*additional properties: false* + - **description**: *string* + - **expression**: *string* + - **location**: *string* + - **title**: *string* +- **quotas**: *object* +
*additional properties: false* + - **`^[a-zA-Z0-9_-]+$`**: *object* +
*additional properties: false* + - ⁺**service**: *string* + - ⁺**quota_id**: *string* + - ⁺**preferred_value**: *number* + - **dimensions**: *object* + *additional properties: String* + - **justification**: *string* + - **contact_email**: *string* + - **annotations**: *object* + *additional properties: String* + - **ignore_safety_checks**: *string* +
*enum: ['QUOTA_DECREASE_BELOW_USAGE', 'QUOTA_DECREASE_PERCENTAGE_TOO_HIGH', 'QUOTA_SAFETY_CHECK_UNSPECIFIED']* +- **parent**: *string* +- **prefix**: *string* +- **project_reuse**: *object* +
*additional properties: false* + - **use_data_source**: *boolean* + - **attributes**: *object* + - ⁺**name**: *string* + - ⁺**number**: *number* + - **services_enabled**: *array* + - items: *string* +- **project_template**: *string* +- **service_accounts**: *object* +
*additional properties: false* + - **`^[a-z0-9-]+$`**: *object* +
*additional properties: false* + - **display_name**: *string* + - **iam**: *reference([iam](#refs-iam))* + - **iam_self_roles**: *array* + - items: *string* + - **iam_project_roles**: *reference([iam_project_roles](#refs-iam_project_roles))* + - **iam_sa_roles**: *reference([iam_sa_roles](#refs-iam_sa_roles))* +- **service_encryption_key_ids**: *object* +
*additional properties: false* + - **`^[a-z-]+\.googleapis\.com$`**: *array* + - items: *string* +- **services**: *array* + - items: *string* +
*pattern: ^[a-z-]+\.googleapis\.com$* +- **shared_vpc_host_config**: *object* +
*additional properties: false* + - ⁺**enabled**: *boolean* + - **service_projects**: *array* + - items: *string* +- **shared_vpc_service_config**: *object* +
*additional properties: false* + - ⁺**host_project**: *string* + - **iam_bindings_additive**: *reference([iam_bindings_additive](#refs-iam_bindings_additive))* + - **network_users**: *array* + - items: *string* + - **service_agent_iam**: *object* + - **`^[a-z0-9_-]+$`**: *array* + - items: *string* + - **service_agent_subnet_iam**: *object* + - **`^[a-z0-9_-]+$`**: *array* + - items: *string* + - **service_iam_grants**: *array* + - items: *string* + - **network_subnet_users**: *object* + - **`^[a-z0-9_-]+$`**: *array* + - items: *string* +- **tag_bindings**: *object* +
*additional properties: false* + - **`^[a-z0-9_-]+$`**: *string* +- **tags**: *object* + *additional properties: Object* +- **universe**: *object* +
*additional properties: false* + - **prefix**: *string* + - **forced_jit_service_identities**: *array* + - items: *string* + - **unavailable_services**: *array* + - items: *string* + - **unavailable_service_identities**: *array* + - items: *string* +- **vpc_sc**: *object* + - ⁺**perimeter_name**: *string* + - **is_dry_run**: *boolean* +- **datasets**: *object* +
*additional properties: false* + - **`^[a-z0-9_]+$`**: *object* +
*additional properties: false* + - **friendly_name**: *string* + - **location**: *string* + +## Definitions + +- **bucket**: *object* +
*additional properties: false* + - **name**: *string* + - **create**: *boolean* + - **description**: *string* + - **iam**: *reference([iam](#refs-iam))* + - **iam_bindings**: *reference([iam_bindings](#refs-iam_bindings))* + - **iam_bindings_additive**: *reference([iam_bindings_additive](#refs-iam_bindings_additive))* + - **force_destroy**: *boolean* + - **labels**: *object* + *additional properties: String* + - **location**: *string* + - **managed_folders**: *object* +
*additional properties: false* + - **`^[a-zA-Z0-9][a-zA-Z0-9_/-]+$`**: *object* +
*additional properties: false* + - **force_destroy**: *boolean* + - **iam**: *reference([iam](#refs-iam))* + - **iam_bindings**: *reference([iam_bindings](#refs-iam_bindings))* + - **iam_bindings_additive**: *reference([iam_bindings_additive](#refs-iam_bindings_additive))* + - **prefix**: *string* + - **storage_class**: *string* + - **uniform_bucket_level_access**: *boolean* + - **versioning**: *boolean* + - **retention_policy**: *object* +
*additional properties: false* + - **retention_period**: *number* + - **is_locked**: *boolean* + - **enable_object_retention**: *boolean* +- **buckets**: *object* +
*additional properties: false* + - **`^[a-z0-9-]+$`**: *reference([bucket](#refs-bucket))* +- **iam**: *object* +
*additional properties: false* + - **`^(?:roles/|\$custom_roles:)`**: *array* + - items: *string* +
*pattern: ^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:||\$iam_principals:[a-z0-9_-]+)* +- **iam_bindings**: *object* +
*additional properties: false* + - **`^[a-z0-9_-]+$`**: *object* +
*additional properties: false* + - **members**: *array* + - items: *string* +
*pattern: ^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\$iam_principals:[a-z0-9_-]+)* + - **role**: *string* +
*pattern: ^(?:roles/|\$custom_roles:)* + - **condition**: *object* +
*additional properties: false* + - ⁺**expression**: *string* + - ⁺**title**: *string* + - **description**: *string* +- **iam_bindings_additive**: *object* +
*additional properties: false* + - **`^[a-z0-9_-]+$`**: *object* +
*additional properties: false* + - **member**: *string* +
*pattern: ^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\$iam_principals:[a-z0-9_-]+)* + - **role**: *string* +
*pattern: ^(?:roles/|\$custom_roles:)* + - **condition**: *object* +
*additional properties: false* + - ⁺**expression**: *string* + - ⁺**title**: *string* + - **description**: *string* +- **iam_by_principals**: *object* +
*additional properties: false* + - **`^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\$iam_principals:[a-z0-9_-]+)`**: *array* + - items: *string* +
*pattern: ^(?:roles/|\$custom_roles:)* +- **iam_billing_roles**: *object* +
*additional properties: false* + - **`^[a-z0-9-]+$`**: *array* + - items: *string* +- **iam_folder_roles**: *object* +
*additional properties: false* + - **`^[a-z0-9-]+$`**: *array* + - items: *string* +- **iam_organization_roles**: *object* +
*additional properties: false* + - **`^[a-z0-9-]+$`**: *array* + - items: *string* +- **iam_project_roles**: *object* +
*additional properties: false* + - **`^(?:[a-z0-9-]|\$project_ids:[a-z0-9_-])+$`**: *array* + - items: *string* +- **iam_sa_roles**: *object* +
*additional properties: false* + - **`^(?:\$service_account_ids:|projects/)`**: *array* + - items: *string* +- **iam_storage_roles**: *object* +
*additional properties: false* + - **`^[a-z0-9-]+$`**: *array* + - items: *string* +- **log_bucket**: *object* +
*additional properties: false* + - **description**: *string* + - **kms_key_name**: *string* + - **location**: *string* + - **log_analytics**: *object* +
*additional properties: false* + - **enable**: *boolean* + - **dataset_link_id**: *string* + - **description**: *string* + - **retention**: *number* +- **pam_entitlements**: *object* +
*additional properties: false* + - **`^[a-z][a-z0-9-]{0,61}[a-z0-9]$`**: *object* +
*additional properties: false* + - ⁺**max_request_duration**: *string* + - ⁺**eligible_users**: *array* + - items: *string* + - ⁺**privileged_access**: *array* + - items: *object* +
*additional properties: false* + - ⁺**role**: *string* + - **condition**: *string* + - **requester_justification_config**: *object* +
*additional properties: false* + - **not_mandatory**: *boolean* + - **unstructured**: *boolean* + - **manual_approvals**: *object* +
*additional properties: false* + - ⁺**require_approver_justification**: *boolean* + - ⁺**steps**: *array* + - items: *object* +
*additional properties: false* + - ⁺**approvers**: *array* + - items: *string* + - **approvals_needed**: *number* + - **approver_email_recipients**: *array* + - items: *string* + - **additional_notification_targets**: *object* +
*additional properties: false* + - **admin_email_recipients**: *array* + - items: *string* + - **requester_email_recipients**: *array* + - items: *string* diff --git a/fast/stages/1-vpcsc/schemas/perimeter.schema.json b/fast/stages/1-vpcsc/schemas/perimeter.schema.json deleted file mode 120000 index 28eb7c1d6..000000000 --- a/fast/stages/1-vpcsc/schemas/perimeter.schema.json +++ /dev/null @@ -1 +0,0 @@ -../../../../modules/vpc-sc/schemas/perimeters.schema.json \ No newline at end of file diff --git a/fast/stages/1-vpcsc/schemas/perimeter.schema.json b/fast/stages/1-vpcsc/schemas/perimeter.schema.json new file mode 100644 index 000000000..f3dae8384 --- /dev/null +++ b/fast/stages/1-vpcsc/schemas/perimeter.schema.json @@ -0,0 +1,120 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "perimeters", + "type": "object", + "additionalProperties": false, + "properties": { + "description": { + "type": "string" + }, + "ignore_resource_changes": { + "type": "boolean", + "default": false + }, + "spec": { + "type": "object", + "properties": { + "access_levels": { + "type": "array", + "items": { + "type": "string" + } + }, + "egress_policies": { + "type": "array", + "items": { + "type": "string" + } + }, + "ingress_policies": { + "type": "array", + "items": { + "type": "string" + } + }, + "restricted_services": { + "type": "array", + "items": { + "type": "string" + } + }, + "resources": { + "type": "array", + "items": { + "type": "string" + } + }, + "vpc_accessible_services": { + "$ref": "#/$defs/VpcAccessibleServices" + } + }, + "additionalProperties": false + }, + "status": { + "type": "object", + "properties": { + "access_levels": { + "type": "array", + "items": { + "type": "string" + } + }, + "egress_policies": { + "type": "array", + "items": { + "type": "string" + } + }, + "ingress_policies": { + "type": "array", + "items": { + "type": "string" + } + }, + "resources": { + "type": "array", + "items": { + "type": "string" + } + }, + "restricted_services": { + "type": "array", + "items": { + "type": "string" + } + }, + "vpc_accessible_services": { + "$ref": "#/$defs/VpcAccessibleServices" + } + }, + "additionalProperties": false + }, + "title": { + "type": "string" + }, + "use_explicit_dry_run_spec": { + "type": "boolean", + "default": false + } + }, + "$defs": { + "VpcAccessibleServices": { + "type": "object", + "additionalProperties": false, + "properties": { + "allowed_services": { + "type": "array", + "items": { + "type": "string" + } + }, + "enable_restriction": { + "type": "boolean" + } + }, + "required": [ + "allowed_services" + ] + } + } +} \ No newline at end of file diff --git a/fast/stages/2-security/schemas/project.schema.json b/fast/stages/2-security/schemas/project.schema.json index b41bba991..228c10c06 100644 --- a/fast/stages/2-security/schemas/project.schema.json +++ b/fast/stages/2-security/schemas/project.schema.json @@ -88,6 +88,24 @@ } } }, + "datasets": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z0-9_]+$": { + "type": "object", + "additionalProperties": false, + "properties": { + "friendly_name": { + "type": "string" + }, + "location": { + "type": "string" + } + } + } + } + }, "deletion_policy": { "type": "string", "enum": [ @@ -96,6 +114,33 @@ "ABANDON" ] }, + "factories_config": { + "type": "object", + "additionalProperties": false, + "properties": { + "custom_roles": { + "type": "string" + }, + "observability": { + "type": "string" + }, + "org_policies": { + "type": "string" + }, + "org_policies": { + "type": "string" + }, + "quotas": { + "type": "string" + }, + "scc_sha_custom_modules": { + "type": "string" + }, + "tags": { + "type": "string" + } + } + }, "iam": { "$ref": "#/$defs/iam" }, @@ -108,9 +153,15 @@ "iam_by_principals": { "$ref": "#/$defs/iam_by_principals" }, + "iam_by_principals_additive": { + "$ref": "#/$defs/iam_by_principals" + }, "labels": { "type": "object" }, + "pam_entitlements": { + "$ref": "#/$defs/pam_entitlements" + }, "log_buckets": { "type": "object", "additionalProperties": false, @@ -295,6 +346,9 @@ } } }, + "project_template": { + "type": "string" + }, "service_accounts": { "type": "object", "additionalProperties": false, @@ -482,6 +536,33 @@ } } }, + "universe": { + "type": "object", + "additionalProperties": false, + "properties": { + "prefix": { + "type": "string" + }, + "forced_jit_service_identities": { + "type": "array", + "items": { + "type": "string" + } + }, + "unavailable_services": { + "type": "array", + "items": { + "type": "string" + } + }, + "unavailable_service_identities": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, "vpc_sc": { "type": "object", "additionalItems": false, @@ -506,6 +587,10 @@ "name": { "type": "string" }, + "create": { + "type": "boolean", + "default": true + }, "description": { "type": "string" }, @@ -565,6 +650,21 @@ }, "versioning": { "type": "boolean" + }, + "retention_policy": { + "type": "object", + "additionalProperties": false, + "properties": { + "retention_period": { + "type": "number" + }, + "is_locked": { + "type": "boolean" + } + } + }, + "enable_object_retention": { + "type": "boolean" } } }, @@ -789,6 +889,120 @@ "type": "number" } } + }, + "pam_entitlements": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-z][a-z0-9-]{0,61}[a-z0-9]$": { + "type": "object", + "properties": { + "max_request_duration": { + "type": "string" + }, + "eligible_users": { + "type": "array", + "items": { + "type": "string" + } + }, + "privileged_access": { + "type": "array", + "items": { + "type": "object", + "properties": { + "role": { + "type": "string" + }, + "condition": { + "type": "string" + } + }, + "required": [ + "role" + ], + "additionalProperties": false + } + }, + "requester_justification_config": { + "type": "object", + "properties": { + "not_mandatory": { + "type": "boolean" + }, + "unstructured": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "manual_approvals": { + "type": "object", + "properties": { + "require_approver_justification": { + "type": "boolean" + }, + "steps": { + "type": "array", + "items": { + "type": "object", + "properties": { + "approvers": { + "type": "array", + "items": { + "type": "string" + } + }, + "approvals_needed": { + "type": "number" + }, + "approver_email_recipients": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "approvers" + ], + "additionalProperties": false + } + } + }, + "required": [ + "require_approver_justification", + "steps" + ], + "additionalProperties": false + }, + "additional_notification_targets": { + "type": "object", + "properties": { + "admin_email_recipients": { + "type": "array", + "items": { + "type": "string" + } + }, + "requester_email_recipients": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + } + }, + "required": [ + "max_request_duration", + "eligible_users", + "privileged_access" + ], + "additionalProperties": false + } + } } } -} \ No newline at end of file +} diff --git a/modules/organization/schemas/tags.schema.json b/modules/organization/schemas/tags.schema.json index 08312c959..75a602ac2 100644 --- a/modules/organization/schemas/tags.schema.json +++ b/modules/organization/schemas/tags.schema.json @@ -65,7 +65,7 @@ "type": "array", "items": { "type": "string", - "pattern": "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|[a-z])" + "pattern": "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\\$iam_principals:[a-z0-9_-]+)" } } } @@ -82,7 +82,7 @@ "type": "array", "items": { "type": "string", - "pattern": "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|[a-z])" + "pattern": "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\\$iam_principals:[a-z0-9_-]+)" } }, "role": { @@ -122,7 +122,7 @@ "properties": { "member": { "type": "string", - "pattern": "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|[a-z])" + "pattern": "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\\$iam_principals:[a-z0-9_-]+)" }, "role": { "type": "string", diff --git a/modules/organization/schemas/tags.schema.md b/modules/organization/schemas/tags.schema.md index d33e47b15..712fbbbc6 100644 --- a/modules/organization/schemas/tags.schema.md +++ b/modules/organization/schemas/tags.schema.md @@ -30,14 +30,14 @@
*additional properties: false* - **`^roles/`**: *array* - items: *string* -
*pattern: ^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|[a-z])* +
*pattern: ^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\$iam_principals:[a-z0-9_-]+)* - **iam_bindings**: *object*
*additional properties: false* - **`^[a-z0-9_-]+$`**: *object*
*additional properties: false* - **members**: *array* - items: *string* -
*pattern: ^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|[a-z])* +
*pattern: ^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\$iam_principals:[a-z0-9_-]+)* - **role**: *string*
*pattern: ^roles/* - **condition**: *object* @@ -50,7 +50,7 @@ - **`^[a-z0-9_-]+$`**: *object*
*additional properties: false* - **member**: *string* -
*pattern: ^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|[a-z])* +
*pattern: ^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\$iam_principals:[a-z0-9_-]+)* - **role**: *string*
*pattern: ^[a-zA-Z0-9_/]+$* - **condition**: *object* diff --git a/modules/vpc-sc/README.md b/modules/vpc-sc/README.md index dbe39a861..438d07c46 100644 --- a/modules/vpc-sc/README.md +++ b/modules/vpc-sc/README.md @@ -286,7 +286,7 @@ status: - "storage.googleapis.com" enable_restriction: yes -# tftest-file id=p1 path=data/perimeters/perimeter-north.yaml schema=perimeters.schema.json +# tftest-file id=p1 path=data/perimeters/perimeter-north.yaml schema=perimeter.schema.json ``` ```yaml @@ -309,7 +309,7 @@ status: allowed_services: - storage.googleapis.com enable_restriction: true -# tftest-file id=p1 path=data/perimeters/perimeter-north.yaml schema=perimeters.schema.json +# tftest-file id=p1 path=data/perimeters/perimeter-north.yaml schema=perimeter.schema.json ``` ```yaml diff --git a/modules/vpc-sc/schemas/perimeters.schema.json b/modules/vpc-sc/schemas/perimeter.schema.json similarity index 100% rename from modules/vpc-sc/schemas/perimeters.schema.json rename to modules/vpc-sc/schemas/perimeter.schema.json diff --git a/tools/duplicate-diff.py b/tools/duplicate-diff.py index c4b8af5de..fd149a640 100755 --- a/tools/duplicate-diff.py +++ b/tools/duplicate-diff.py @@ -21,7 +21,7 @@ import os # List of folders and files that are expected to have same content duplicates = [ - # File comparison + # file comparison [ "fast/stages/0-org-setup/datasets/classic/defaults.yaml", "fast/stages/0-org-setup/datasets/hardened/defaults.yaml", @@ -40,7 +40,7 @@ duplicates = [ "fast/stages/2-networking-b-nva/data/cidrs.yaml", "fast/stages/2-networking-c-separate-envs/data/cidrs.yaml", ], - # Deep recursive folder comparison + # deep recursive folder comparison [ "fast/stages/0-org-setup/datasets/classic/organization/custom-roles", "fast/stages/0-org-setup/datasets/hardened/organization/custom-roles", @@ -49,6 +49,92 @@ duplicates = [ "fast/stages/0-org-setup/datasets/classic/organization/tags", "fast/stages/0-org-setup/datasets/hardened/organization/tags", ], + # schemas + [ + "fast/stages/1-vpcsc/schemas/access-level.schema.json", + "modules/vpc-sc/schemas/access-level.schema.json", + ], + [ + "fast/stages/3-data-platform-dev/schemas/aspect-type.schema.json", + "modules/dataplex-aspect-types/schemas/aspect-type.schema.json", + ], + [ + "fast/stages/2-project-factory/schemas/budget.schema.json", + "fast/stages/0-org-setup/schemas/budget.schema.json", + "modules/billing-account/schemas/budget.schema.json", + "modules/project-factory/schemas/budget.schema.json", + ], + [ + "fast/stages/0-org-setup/schemas/custom-constraint.schema.json", + "modules/organization/schemas/org-policy-custom-constraint.schema.json", + ], + [ + "fast/stages/0-org-setup/schemas/custom-role.schema.json", + "modules/project/schemas/custom-role.schema.json", + "modules/organization/schemas/custom-role.schema.json", + ], + [ + "fast/stages/1-vpcsc/schemas/egress-policy.schema.json", + "modules/vpc-sc/schemas/egress-policy.schema.json", + ], + [ + "fast/stages/2-networking-a-simple/schemas/firewall-policy-rules.schema.json", + "fast/stages/2-networking-c-separate-envs/schemas/firewall-policy-rules.schema.json", + "fast/stages/2-networking-b-nva/schemas/firewall-policy-rules.schema.json", + "modules/net-firewall-policy/schemas/firewall-policy-rules.schema.json", + ], + [ + "fast/stages/2-networking-a-simple/schemas/firewall-rules.schema.json", + "fast/stages/2-networking-c-separate-envs/schemas/firewall-rules.schema.json", + "fast/stages/2-networking-b-nva/schemas/firewall-rules.schema.json", + "modules/net-vpc-firewall/schemas/firewall-rules.schema.json", + ], + [ + "fast/stages/2-project-factory/schemas/folder.schema.json", + "fast/stages/0-org-setup/schemas/folder.schema.json", + "modules/project-factory/schemas/folder.schema.json", + ], + [ + "fast/stages/1-vpcsc/schemas/ingress-policy.schema.json", + "modules/vpc-sc/schemas/ingress-policy.schema.json", + ], + [ + "fast/stages/0-org-setup/schemas/org-policies.schema.json", + "modules/folder/schemas/org-policies.schema.json", + "modules/project/schemas/org-policies.schema.json", + "modules/organization/schemas/org-policies.schema.json", + ], + [ + "modules/folder/schemas/pam-entitlements.schema.json", + "modules/project/schemas/pam-entitlements.schema.json", + "modules/organization/schemas/pam-entitlements.schema.json", + ], + [ + "fast/stages/1-vpcsc/schemas/perimeter.schema.json", + "modules/vpc-sc/schemas/perimeter.schema.json", + ], + [ + "fast/stages/2-project-factory/schemas/project.schema.json", + "fast/stages/0-org-setup/schemas/project.schema.json", + "fast/stages/2-security/schemas/project.schema.json", + "modules/project-factory/schemas/project.schema.json", + ], + [ + "modules/folder/schemas/scc-sha-custom-modules.schema.json", + "modules/project/schemas/scc-sha-custom-modules.schema.json", + "modules/organization/schemas/scc-sha-custom-modules.schema.json", + ], + [ + "fast/stages/2-networking-a-simple/schemas/subnet.schema.json", + "fast/stages/2-networking-c-separate-envs/schemas/subnet.schema.json", + "fast/stages/2-networking-b-nva/schemas/subnet.schema.json", + "modules/net-vpc/schemas/subnet.schema.json", + ], + [ + "fast/stages/0-org-setup/schemas/tags.schema.json", + "modules/project/schemas/tags.schema.json", + "modules/organization/schemas/tags.schema.json", + ], ]