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 \
|
tools/*.py \
|
||||||
blueprints/cloud-operations/network-dashboard/src/*py \
|
blueprints/cloud-operations/network-dashboard/src/*py \
|
||||||
blueprints/cloud-operations/network-dashboard/src/plugins/*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
|
requests
|
||||||
yamale
|
yamale
|
||||||
yapf
|
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