Merge pull request #1359 from GoogleCloudPlatform/jccb/blueprint-validator
Blueprint metadata validator
This commit is contained in:
commit
bf9e8eeb5f
|
@ -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
|
||||
|
|
|
@ -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