Merge branch 'master' into serverless-program
This commit is contained in:
commit
76ce3e8b3e
|
@ -75,3 +75,8 @@ jobs:
|
|||
tools/*.py \
|
||||
blueprints/cloud-operations/network-dashboard/src/*py \
|
||||
blueprints/cloud-operations/network-dashboard/src/plugins/*py
|
||||
|
||||
- name: Check blueprint metadata
|
||||
id: metadata
|
||||
run: |
|
||||
python tools/validate_metadata.py -v blueprints
|
||||
|
|
|
@ -129,7 +129,7 @@ spec:
|
|||
type: string
|
||||
default: null
|
||||
required: false
|
||||
- name: service_encryption_keys
|
||||
- name: service_encryption_keys
|
||||
description: Cloud KMS to use to encrypt different services. Key location should match service region.
|
||||
type: |-
|
||||
object({
|
||||
|
|
|
@ -247,9 +247,9 @@ module "gke" {
|
|||
|---|---|:---:|:---:|:---:|
|
||||
| [billing_account_id](variables.tf#L17) | Billing account id. | <code>string</code> | ✓ | |
|
||||
| [folder_id](variables.tf#L132) | Folder used for the GKE project in folders/nnnnnnnnnnn format. | <code>string</code> | ✓ | |
|
||||
| [prefix](variables.tf#L179) | Prefix used for resource names. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L188) | ID of the project that will contain all the clusters. | <code>string</code> | ✓ | |
|
||||
| [vpc_config](variables.tf#L200) | Shared VPC project and VPC details. | <code title="object({ host_project_id = string vpc_self_link = string })">object({…})</code> | ✓ | |
|
||||
| [prefix](variables.tf#L183) | Prefix used for resource names. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L192) | ID of the project that will contain all the clusters. | <code>string</code> | ✓ | |
|
||||
| [vpc_config](variables.tf#L204) | Shared VPC project and VPC details. | <code title="object({ host_project_id = string vpc_self_link = string })">object({…})</code> | ✓ | |
|
||||
| [clusters](variables.tf#L22) | Clusters configuration. Refer to the gke-cluster module for type details. | <code title="map(object({ cluster_autoscaling = optional(any) description = optional(string) enable_addons = optional(any, { horizontal_pod_autoscaling = true, http_load_balancing = true }) enable_features = optional(any, { workload_identity = true }) issue_client_certificate = optional(bool, false) labels = optional(map(string)) location = string logging_config = optional(list(string), ["SYSTEM_COMPONENTS"]) maintenance_config = optional(any, { daily_window_start_time = "03:00" recurring_window = null maintenance_exclusion = [] }) max_pods_per_node = optional(number, 110) min_master_version = optional(string) monitoring_config = optional(object({ enable_components = optional(list(string), ["SYSTEM_COMPONENTS"]) managed_prometheus = optional(bool) })) node_locations = optional(list(string)) private_cluster_config = optional(any) release_channel = optional(string) vpc_config = object({ subnetwork = string network = optional(string) secondary_range_blocks = optional(object({ pods = string services = string })) secondary_range_names = optional(object({ pods = string services = string }), { pods = "pods", services = "services" }) master_authorized_ranges = optional(map(string)) master_ipv4_cidr_block = optional(string) }) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [fleet_configmanagement_clusters](variables.tf#L70) | Config management features enabled on specific sets of member clusters, in config name => [cluster name] format. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [fleet_configmanagement_templates](variables.tf#L77) | Sets of config management configurations that can be applied to member clusters, in config name => {options} format. | <code title="map(object({ binauthz = bool config_sync = object({ git = object({ gcp_service_account_email = string https_proxy = string policy_dir = string secret_type = string sync_branch = string sync_repo = string sync_rev = string sync_wait_secs = number }) prevent_drift = string source_format = string }) hierarchy_controller = object({ enable_hierarchical_resource_quota = bool enable_pod_tree_labels = bool }) policy_controller = object({ audit_interval_seconds = number exemptable_namespaces = list(string) log_denies_enabled = bool referential_rules_enabled = bool template_library_installed = bool }) version = string }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
|
@ -258,8 +258,8 @@ module "gke" {
|
|||
| [group_iam](variables.tf#L137) | Project-level IAM bindings for groups. Use group emails as keys, list of roles as values. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [iam](variables.tf#L144) | Project-level authoritative IAM bindings for users and service accounts in {ROLE => [MEMBERS]} format. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [labels](variables.tf#L151) | Project-level labels. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [nodepools](variables.tf#L157) | Nodepools configuration. Refer to the gke-nodepool module for type details. | <code title="map(map(object({ gke_version = optional(string) labels = optional(map(string), {}) max_pods_per_node = optional(number) name = optional(string) node_config = optional(any, { disk_type = "pd-balanced" }) node_count = optional(map(number), { initial = 1 }) node_locations = optional(list(string)) nodepool_config = optional(any) pod_range = optional(any) reservation_affinity = optional(any) service_account = optional(any) sole_tenant_nodegroup = optional(string) tags = optional(list(string)) taints = optional(list(any)) })))">map(map(object({…})))</code> | | <code>{}</code> |
|
||||
| [project_services](variables.tf#L193) | Additional project services to enable. | <code>list(string)</code> | | <code>[]</code> |
|
||||
| [nodepools](variables.tf#L157) | Nodepools configuration. Refer to the gke-nodepool module for type details. | <code title="map(map(object({ gke_version = optional(string) labels = optional(map(string), {}) max_pods_per_node = optional(number) name = optional(string) node_config = optional(any, { disk_type = "pd-balanced" }) node_count = optional(map(number), { initial = 1 }) node_locations = optional(list(string)) nodepool_config = optional(any) pod_range = optional(any) reservation_affinity = optional(any) service_account = optional(any) sole_tenant_nodegroup = optional(string) tags = optional(list(string)) taints = optional(list(object({ key = string value = string effect = string }))) })))">map(map(object({…})))</code> | | <code>{}</code> |
|
||||
| [project_services](variables.tf#L197) | Additional project services to enable. | <code>list(string)</code> | | <code>[]</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -170,7 +170,11 @@ variable "nodepools" {
|
|||
service_account = optional(any)
|
||||
sole_tenant_nodegroup = optional(string)
|
||||
tags = optional(list(string))
|
||||
taints = optional(list(any))
|
||||
taints = optional(list(object({
|
||||
key = string
|
||||
value = string
|
||||
effect = string
|
||||
})))
|
||||
})))
|
||||
default = {}
|
||||
nullable = false
|
||||
|
|
|
@ -166,8 +166,8 @@ Leave all these variables unset (or set to `null`) to disable fleet management.
|
|||
| [billing_account](variables.tf#L29) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | <code title="object({ id = string is_org_level = optional(bool, true) })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [folder_ids](variables.tf#L153) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object({ gke-dev = string })">object({…})</code> | ✓ | | <code>1-resman</code> |
|
||||
| [host_project_ids](variables.tf#L168) | Host project for the shared VPC. | <code title="object({ dev-spoke-0 = string })">object({…})</code> | ✓ | | <code>2-networking</code> |
|
||||
| [prefix](variables.tf#L217) | Prefix used for resources that need unique names. | <code>string</code> | ✓ | | |
|
||||
| [vpc_self_links](variables.tf#L233) | Self link for the shared VPC. | <code title="object({ dev-spoke-0 = string })">object({…})</code> | ✓ | | <code>2-networking</code> |
|
||||
| [prefix](variables.tf#L221) | Prefix used for resources that need unique names. | <code>string</code> | ✓ | | |
|
||||
| [vpc_self_links](variables.tf#L237) | Self link for the shared VPC. | <code title="object({ dev-spoke-0 = string })">object({…})</code> | ✓ | | <code>2-networking</code> |
|
||||
| [clusters](variables.tf#L42) | Clusters configuration. Refer to the gke-cluster module for type details. | <code title="map(object({ cluster_autoscaling = optional(any) description = optional(string) enable_addons = optional(any, { horizontal_pod_autoscaling = true, http_load_balancing = true }) enable_features = optional(any, { workload_identity = true }) issue_client_certificate = optional(bool, false) labels = optional(map(string)) location = string logging_config = optional(list(string), ["SYSTEM_COMPONENTS"]) maintenance_config = optional(any, { daily_window_start_time = "03:00" recurring_window = null maintenance_exclusion = [] }) max_pods_per_node = optional(number, 110) min_master_version = optional(string) monitoring_config = optional(object({ enable_components = optional(list(string), ["SYSTEM_COMPONENTS"]) managed_prometheus = optional(bool) })) node_locations = optional(list(string)) private_cluster_config = optional(any) release_channel = optional(string) vpc_config = object({ subnetwork = string network = optional(string) secondary_range_blocks = optional(object({ pods = string services = string })) secondary_range_names = optional(object({ pods = string services = string }), { pods = "pods", services = "services" }) master_authorized_ranges = optional(map(string)) master_ipv4_cidr_block = optional(string) }) }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
| [fleet_configmanagement_clusters](variables.tf#L90) | Config management features enabled on specific sets of member clusters, in config name => [cluster name] format. | <code>map(list(string))</code> | | <code>{}</code> | |
|
||||
| [fleet_configmanagement_templates](variables.tf#L98) | Sets of config management configurations that can be applied to member clusters, in config name => {options} format. | <code title="map(object({ binauthz = bool config_sync = object({ git = object({ gcp_service_account_email = string https_proxy = string policy_dir = string secret_type = string sync_branch = string sync_repo = string sync_rev = string sync_wait_secs = number }) prevent_drift = string source_format = string }) hierarchy_controller = object({ enable_hierarchical_resource_quota = bool enable_pod_tree_labels = bool }) policy_controller = object({ audit_interval_seconds = number exemptable_namespaces = list(string) log_denies_enabled = bool referential_rules_enabled = bool template_library_installed = bool }) version = string }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
|
@ -176,9 +176,9 @@ Leave all these variables unset (or set to `null`) to disable fleet management.
|
|||
| [group_iam](variables.tf#L161) | Project-level authoritative IAM bindings for groups in {GROUP_EMAIL => [ROLES]} format. Use group emails as keys, list of roles as values. | <code>map(list(string))</code> | | <code>{}</code> | |
|
||||
| [iam](variables.tf#L176) | Project-level authoritative IAM bindings for users and service accounts in {ROLE => [MEMBERS]} format. | <code>map(list(string))</code> | | <code>{}</code> | |
|
||||
| [labels](variables.tf#L183) | Project-level labels. | <code>map(string)</code> | | <code>{}</code> | |
|
||||
| [nodepools](variables.tf#L189) | Nodepools configuration. Refer to the gke-nodepool module for type details. | <code title="map(map(object({ gke_version = optional(string) labels = optional(map(string), {}) max_pods_per_node = optional(number) name = optional(string) node_config = optional(any, { disk_type = "pd-balanced" }) node_count = optional(map(number), { initial = 1 }) node_locations = optional(list(string)) nodepool_config = optional(any) pod_range = optional(any) reservation_affinity = optional(any) service_account = optional(any) sole_tenant_nodegroup = optional(string) tags = optional(list(string)) taints = optional(list(any)) })))">map(map(object({…})))</code> | | <code>{}</code> | |
|
||||
| [outputs_location](variables.tf#L211) | Path where providers, tfvars files, and lists for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [project_services](variables.tf#L226) | Additional project services to enable. | <code>list(string)</code> | | <code>[]</code> | |
|
||||
| [nodepools](variables.tf#L189) | Nodepools configuration. Refer to the gke-nodepool module for type details. | <code title="map(map(object({ gke_version = optional(string) labels = optional(map(string), {}) max_pods_per_node = optional(number) name = optional(string) node_config = optional(any, { disk_type = "pd-balanced" }) node_count = optional(map(number), { initial = 1 }) node_locations = optional(list(string)) nodepool_config = optional(any) pod_range = optional(any) reservation_affinity = optional(any) service_account = optional(any) sole_tenant_nodegroup = optional(string) tags = optional(list(string)) taints = optional(list(object({ key = string value = string effect = string }))) })))">map(map(object({…})))</code> | | <code>{}</code> | |
|
||||
| [outputs_location](variables.tf#L215) | Path where providers, tfvars files, and lists for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [project_services](variables.tf#L230) | Additional project services to enable. | <code>list(string)</code> | | <code>[]</code> | |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -202,7 +202,11 @@ variable "nodepools" {
|
|||
service_account = optional(any)
|
||||
sole_tenant_nodegroup = optional(string)
|
||||
tags = optional(list(string))
|
||||
taints = optional(list(any))
|
||||
taints = optional(list(object({
|
||||
key = string
|
||||
value = string
|
||||
effect = string
|
||||
})))
|
||||
})))
|
||||
default = {}
|
||||
nullable = false
|
||||
|
|
|
@ -0,0 +1,966 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://github.com/GoogleCloudPlatform/cloud-foundation-toolkit/cli/bpmetadata/blueprint-metadata",
|
||||
"$ref": "#/$defs/BlueprintMetadata",
|
||||
"$defs": {
|
||||
"BlueprintActuationTool": {
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"version": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"BlueprintArchitecture": {
|
||||
"properties": {
|
||||
"diagram": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"diagram",
|
||||
"description"
|
||||
]
|
||||
},
|
||||
"BlueprintAuthor": {
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"title"
|
||||
]
|
||||
},
|
||||
"BlueprintCloudProduct": {
|
||||
"properties": {
|
||||
"productId": {
|
||||
"type": "string"
|
||||
},
|
||||
"pageUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"label": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"pageUrl"
|
||||
]
|
||||
},
|
||||
"BlueprintContent": {
|
||||
"properties": {
|
||||
"architecture": {
|
||||
"$ref": "#/$defs/BlueprintArchitecture"
|
||||
},
|
||||
"diagrams": {
|
||||
"items": {
|
||||
"$ref": "#/$defs/BlueprintDiagram"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"documentation": {
|
||||
"items": {
|
||||
"$ref": "#/$defs/BlueprintListContent"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"subBlueprints": {
|
||||
"items": {
|
||||
"$ref": "#/$defs/BlueprintMiscContent"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"examples": {
|
||||
"items": {
|
||||
"$ref": "#/$defs/BlueprintMiscContent"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"BlueprintCostEstimate": {
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"description",
|
||||
"url"
|
||||
]
|
||||
},
|
||||
"BlueprintDescription": {
|
||||
"properties": {
|
||||
"tagline": {
|
||||
"type": "string"
|
||||
},
|
||||
"detailed": {
|
||||
"type": "string"
|
||||
},
|
||||
"preDeploy": {
|
||||
"type": "string"
|
||||
},
|
||||
"html": {
|
||||
"type": "string"
|
||||
},
|
||||
"eulaUrls": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"architecture": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"BlueprintDiagram": {
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"altText": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
]
|
||||
},
|
||||
"BlueprintInfo": {
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"source": {
|
||||
"$ref": "#/$defs/BlueprintRepoDetail"
|
||||
},
|
||||
"version": {
|
||||
"type": "string"
|
||||
},
|
||||
"actuationTool": {
|
||||
"$ref": "#/$defs/BlueprintActuationTool"
|
||||
},
|
||||
"description": {
|
||||
"$ref": "#/$defs/BlueprintDescription"
|
||||
},
|
||||
"icon": {
|
||||
"type": "string"
|
||||
},
|
||||
"deploymentDuration": {
|
||||
"$ref": "#/$defs/BlueprintTimeEstimate"
|
||||
},
|
||||
"costEstimate": {
|
||||
"$ref": "#/$defs/BlueprintCostEstimate"
|
||||
},
|
||||
"cloudProducts": {
|
||||
"items": {
|
||||
"$ref": "#/$defs/BlueprintCloudProduct"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"quotaDetails": {
|
||||
"items": {
|
||||
"$ref": "#/$defs/BlueprintQuotaDetail"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"author": {
|
||||
"$ref": "#/$defs/BlueprintAuthor"
|
||||
},
|
||||
"softwareGroups": {
|
||||
"items": {
|
||||
"$ref": "#/$defs/BlueprintSoftwareGroup"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"supportInfo": {
|
||||
"$ref": "#/$defs/BlueprintSupport"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"title",
|
||||
"source"
|
||||
]
|
||||
},
|
||||
"BlueprintInterface": {
|
||||
"properties": {
|
||||
"variables": {
|
||||
"items": {
|
||||
"$ref": "#/$defs/BlueprintVariable"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"variableGroups": {
|
||||
"items": {
|
||||
"$ref": "#/$defs/BlueprintVariableGroup"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"outputs": {
|
||||
"items": {
|
||||
"$ref": "#/$defs/BlueprintOutput"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"BlueprintListContent": {
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"title"
|
||||
]
|
||||
},
|
||||
"BlueprintMetadata": {
|
||||
"properties": {
|
||||
"apiVersion": {
|
||||
"type": "string"
|
||||
},
|
||||
"kind": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"$ref": "#/$defs/ObjectMeta"
|
||||
},
|
||||
"spec": {
|
||||
"$ref": "#/$defs/BlueprintMetadataSpec"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"spec"
|
||||
]
|
||||
},
|
||||
"BlueprintMetadataSpec": {
|
||||
"properties": {
|
||||
"info": {
|
||||
"$ref": "#/$defs/BlueprintInfo"
|
||||
},
|
||||
"content": {
|
||||
"$ref": "#/$defs/BlueprintContent"
|
||||
},
|
||||
"interfaces": {
|
||||
"$ref": "#/$defs/BlueprintInterface"
|
||||
},
|
||||
"requirements": {
|
||||
"$ref": "#/$defs/BlueprintRequirements"
|
||||
},
|
||||
"ui": {
|
||||
"$ref": "#/$defs/BlueprintUI"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"BlueprintMiscContent": {
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"location": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
]
|
||||
},
|
||||
"BlueprintOutput": {
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
]
|
||||
},
|
||||
"BlueprintQuotaDetail": {
|
||||
"properties": {
|
||||
"variable": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"GCE_INSTANCE",
|
||||
"GCE_DISK"
|
||||
]
|
||||
},
|
||||
"quotaType": {
|
||||
"patternProperties": {
|
||||
".*": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"type",
|
||||
"quotaType"
|
||||
]
|
||||
},
|
||||
"BlueprintRepoDetail": {
|
||||
"properties": {
|
||||
"repo": {
|
||||
"type": "string"
|
||||
},
|
||||
"sourceType": {
|
||||
"type": "string"
|
||||
},
|
||||
"dir": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"repo",
|
||||
"sourceType"
|
||||
]
|
||||
},
|
||||
"BlueprintRequirements": {
|
||||
"properties": {
|
||||
"roles": {
|
||||
"items": {
|
||||
"$ref": "#/$defs/BlueprintRoles"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"services": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"BlueprintRoles": {
|
||||
"properties": {
|
||||
"level": {
|
||||
"type": "string"
|
||||
},
|
||||
"roles": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"level",
|
||||
"roles"
|
||||
]
|
||||
},
|
||||
"BlueprintSoftware": {
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"version": {
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
},
|
||||
"licenseUrl": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"title"
|
||||
]
|
||||
},
|
||||
"BlueprintSoftwareGroup": {
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"UNSPECIFIED",
|
||||
"OS"
|
||||
]
|
||||
},
|
||||
"software": {
|
||||
"items": {
|
||||
"$ref": "#/$defs/BlueprintSoftware"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"BlueprintSupport": {
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
},
|
||||
"entity": {
|
||||
"type": "string"
|
||||
},
|
||||
"showSupportId": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"description"
|
||||
]
|
||||
},
|
||||
"BlueprintTimeEstimate": {
|
||||
"properties": {
|
||||
"configuration": {
|
||||
"type": "integer"
|
||||
},
|
||||
"deployment": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"BlueprintUI": {
|
||||
"properties": {
|
||||
"input": {
|
||||
"$ref": "#/$defs/BlueprintUIInput"
|
||||
},
|
||||
"runtime": {
|
||||
"$ref": "#/$defs/BlueprintUIOutput"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"BlueprintUIInput": {
|
||||
"properties": {
|
||||
"variables": {
|
||||
"patternProperties": {
|
||||
".*": {
|
||||
"$ref": "#/$defs/DisplayVariable"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"sections": {
|
||||
"items": {
|
||||
"$ref": "#/$defs/DisplaySection"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"BlueprintUIOutput": {
|
||||
"properties": {
|
||||
"outputMessage": {
|
||||
"type": "string"
|
||||
},
|
||||
"suggestedActions": {
|
||||
"items": {
|
||||
"$ref": "#/$defs/UIActionItem"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"BlueprintVariable": {
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"default": true,
|
||||
"required": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"BlueprintVariableGroup": {
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"variables": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
]
|
||||
},
|
||||
"DisplaySection": {
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"tooltip": {
|
||||
"type": "string"
|
||||
},
|
||||
"subtext": {
|
||||
"type": "string"
|
||||
},
|
||||
"parent": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
]
|
||||
},
|
||||
"DisplayVariable": {
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"invisible": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"tooltip": {
|
||||
"type": "string"
|
||||
},
|
||||
"placeholder": {
|
||||
"type": "string"
|
||||
},
|
||||
"regexValidation": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": {
|
||||
"type": "integer"
|
||||
},
|
||||
"maxItems": {
|
||||
"type": "integer"
|
||||
},
|
||||
"minLength": {
|
||||
"type": "integer"
|
||||
},
|
||||
"maxLength": {
|
||||
"type": "integer"
|
||||
},
|
||||
"min": {
|
||||
"type": "integer"
|
||||
},
|
||||
"max": {
|
||||
"type": "integer"
|
||||
},
|
||||
"section": {
|
||||
"type": "string"
|
||||
},
|
||||
"x-googleProperty": {
|
||||
"$ref": "#/$defs/GooglePropertyExtension"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
]
|
||||
},
|
||||
"GCEDiskSizeExtension": {
|
||||
"properties": {
|
||||
"diskTypeVariable": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"diskTypeVariable"
|
||||
]
|
||||
},
|
||||
"GCEExternalIPExtension": {
|
||||
"properties": {
|
||||
"networkVariable": {
|
||||
"type": "string"
|
||||
},
|
||||
"externalIpType": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"networkVariable"
|
||||
]
|
||||
},
|
||||
"GCEFirewallExtension": {
|
||||
"properties": {
|
||||
"networkVariable": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"networkVariable"
|
||||
]
|
||||
},
|
||||
"GCEFirewallRangeExtension": {
|
||||
"properties": {
|
||||
"firewallVariable": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"firewallVariable"
|
||||
]
|
||||
},
|
||||
"GCEGPUCountExtension": {
|
||||
"properties": {
|
||||
"machineTypeVariable": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"machineTypeVariable"
|
||||
]
|
||||
},
|
||||
"GCEGPUTypeExtension": {
|
||||
"properties": {
|
||||
"machineType": {
|
||||
"type": "string"
|
||||
},
|
||||
"gpuType": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"machineType"
|
||||
]
|
||||
},
|
||||
"GCEGenericResourceExtension": {
|
||||
"properties": {
|
||||
"resourceVariable": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"resourceVariable"
|
||||
]
|
||||
},
|
||||
"GCEIPForwardingExtension": {
|
||||
"properties": {
|
||||
"networkVariable": {
|
||||
"type": "string"
|
||||
},
|
||||
"notConfigurable": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"networkVariable"
|
||||
]
|
||||
},
|
||||
"GCELocationExtension": {
|
||||
"properties": {
|
||||
"allowlistedZones": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"allowlistedRegions": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"GCEMachineTypeExtension": {
|
||||
"properties": {
|
||||
"minCpu": {
|
||||
"type": "integer"
|
||||
},
|
||||
"minRamGb": {
|
||||
"type": "integer"
|
||||
},
|
||||
"disallowCustomMachineTypes": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"GCENetworkExtension": {
|
||||
"properties": {
|
||||
"allowSharedVpcs": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"machineTypeVariable": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"machineTypeVariable"
|
||||
]
|
||||
},
|
||||
"GCESubnetworkExtension": {
|
||||
"properties": {
|
||||
"networkVariable": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"networkVariable"
|
||||
]
|
||||
},
|
||||
"GooglePropertyExtension": {
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"EMAIL_ADDRESS",
|
||||
"MULTI_LINE_STRING",
|
||||
"GCE_DISK_IMAGE",
|
||||
"GCE_DISK_TYPE",
|
||||
"GCE_DISK_SIZE",
|
||||
"GCE_MACHINE_TYPE",
|
||||
"GCE_NETWORK",
|
||||
"GCE_ZONE",
|
||||
"GCE_SUBNETWORK",
|
||||
"GCE_REGION",
|
||||
"GCE_GPU_TYPE",
|
||||
"GCE_GPU_COUNT",
|
||||
"GCE_EXTERNAL_IP",
|
||||
"GCE_IP_FORWARDING",
|
||||
"GCE_FIREWALL",
|
||||
"GCE_FIREWALL_RANGE",
|
||||
"GCE_GENERIC_RESOURCE",
|
||||
"GCS_BUCKET",
|
||||
"IAM_SERVICE_ACCOUNT"
|
||||
]
|
||||
},
|
||||
"zoneProperty": {
|
||||
"type": "string"
|
||||
},
|
||||
"gceMachineType": {
|
||||
"$ref": "#/$defs/GCEMachineTypeExtension"
|
||||
},
|
||||
"gceDiskSize": {
|
||||
"$ref": "#/$defs/GCEDiskSizeExtension"
|
||||
},
|
||||
"gceSubnetwork": {
|
||||
"$ref": "#/$defs/GCESubnetworkExtension"
|
||||
},
|
||||
"gceResource": {
|
||||
"$ref": "#/$defs/GCEGenericResourceExtension"
|
||||
},
|
||||
"gceGpuType": {
|
||||
"$ref": "#/$defs/GCEGPUTypeExtension"
|
||||
},
|
||||
"gceGpuCount": {
|
||||
"$ref": "#/$defs/GCEGPUCountExtension"
|
||||
},
|
||||
"gceNetwork": {
|
||||
"$ref": "#/$defs/GCENetworkExtension"
|
||||
},
|
||||
"gceExternalIp": {
|
||||
"$ref": "#/$defs/GCEExternalIPExtension"
|
||||
},
|
||||
"gceIpForwarding": {
|
||||
"$ref": "#/$defs/GCEIPForwardingExtension"
|
||||
},
|
||||
"gceFirewall": {
|
||||
"$ref": "#/$defs/GCEFirewallExtension"
|
||||
},
|
||||
"gceFirewallRange": {
|
||||
"$ref": "#/$defs/GCEFirewallRangeExtension"
|
||||
},
|
||||
"gceZone": {
|
||||
"$ref": "#/$defs/GCELocationExtension"
|
||||
},
|
||||
"gceRegion": {
|
||||
"$ref": "#/$defs/GCELocationExtension"
|
||||
},
|
||||
"iamServiceAccount": {
|
||||
"$ref": "#/$defs/IAMServiceAccountExtension"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"type"
|
||||
]
|
||||
},
|
||||
"IAMServiceAccountExtension": {
|
||||
"properties": {
|
||||
"roles": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"roles"
|
||||
]
|
||||
},
|
||||
"ObjectMeta": {
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"namespace": {
|
||||
"type": "string"
|
||||
},
|
||||
"labels": {
|
||||
"patternProperties": {
|
||||
".*": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"annotations": {
|
||||
"patternProperties": {
|
||||
".*": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"UIActionItem": {
|
||||
"properties": {
|
||||
"heading": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"snippet": {
|
||||
"type": "string"
|
||||
},
|
||||
"showIf": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"heading"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,3 +6,4 @@ marko
|
|||
requests
|
||||
yamale
|
||||
yapf
|
||||
jsonschema
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright 2023 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
'''Validate a YAML file against the standard blueprint metadata schema[1]
|
||||
|
||||
[1] https://github.com/GoogleCloudPlatform/cloud-foundation-toolkit/blob/master/cli/bpmetadata/schema/bpmetadataschema.json
|
||||
'''
|
||||
|
||||
import enum
|
||||
import json
|
||||
import sys
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
|
||||
import click
|
||||
import jsonschema
|
||||
import yaml
|
||||
|
||||
SCHEMA_PATH = Path(__file__).parent / 'bpmetadataschema.json'
|
||||
|
||||
|
||||
class State(enum.Enum):
|
||||
INVALID: int = 0
|
||||
OK: int = 1
|
||||
|
||||
|
||||
@dataclass
|
||||
class ValidationResult:
|
||||
state: State
|
||||
errors: dict[str, str]
|
||||
|
||||
|
||||
def _validate(path: Path, validator) -> ValidationResult:
|
||||
with open(path) as f:
|
||||
metadata = yaml.safe_load(f)
|
||||
|
||||
errors = {
|
||||
error.json_path: error.message
|
||||
for error in validator.iter_errors(metadata)
|
||||
}
|
||||
|
||||
state = State.OK if not errors else State.INVALID
|
||||
return ValidationResult(state=state, errors=errors)
|
||||
|
||||
|
||||
@click.command()
|
||||
@click.argument('dirs', type=click.Path(exists=True, file_okay=False), nargs=-1)
|
||||
@click.option('-v', '--verbose', is_flag=True, default=False,
|
||||
help='Print additional validation details.')
|
||||
def main(dirs: list[str], verbose: bool) -> int:
|
||||
instances = set()
|
||||
for dir_name in dirs:
|
||||
instances |= set(Path(dir_name).glob("**/metadata.yaml"))
|
||||
|
||||
with open(SCHEMA_PATH) as f:
|
||||
schema = json.load(f)
|
||||
validator = jsonschema.validators.Draft202012Validator(schema)
|
||||
|
||||
failed_files = {}
|
||||
for instance in instances:
|
||||
result = _validate(instance, validator)
|
||||
if result.state == State.OK:
|
||||
print(f'[✓] {instance}')
|
||||
else:
|
||||
print(f'[✗] {instance}')
|
||||
failed_files[instance] = result.errors
|
||||
|
||||
if verbose:
|
||||
for file_path, errors in failed_files.items():
|
||||
print(f"\n====== {file_path!s} ======")
|
||||
for path, message in errors.items():
|
||||
print(f"{path}: {message}")
|
||||
|
||||
return 0 if not failed_files else 1
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
Loading…
Reference in New Issue