yaml-language-server
Version:
109 lines • 4.58 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.autoDetectKubernetesSchema = autoDetectKubernetesSchema;
exports.autoDetectCustomResource = autoDetectCustomResource;
exports.getGroupVersionKindFromDocument = getGroupVersionKindFromDocument;
const yamlParser07_1 = require("../parser/yamlParser07");
/**
* Attempt to retrieve the schema for a given YAML document based on the Kubernetes GroupVersionKind (GVK).
*
* First, checks for a schema for a matching builtin resource, then it checks for a schema for a CRD.
*
* @param doc the yaml document being validated
* @param kubernetesSchema the resolved copy of the Kubernetes builtin
* @param crdCatalogURI the catalog uri to use to find schemas for custom resource definitions
* @returns a schema uri, or undefined if no specific schema can be identified
*/
function autoDetectKubernetesSchema(doc, kubernetesSchema, kubernetesSchemaURI, crdCatalogURI) {
const gvk = getGroupVersionKindFromDocument(doc);
if (!gvk || !gvk.group || !gvk.version || !gvk.kind) {
return undefined;
}
const builtinResource = autoDetectBuiltinResource(gvk, kubernetesSchema, kubernetesSchemaURI);
if (builtinResource) {
return builtinResource;
}
const customResource = autoDetectCustomResource(gvk, crdCatalogURI);
if (customResource) {
return customResource;
}
return undefined;
}
function autoDetectBuiltinResource(gvk, kubernetesSchema, kubernetesSchemaURI) {
const { group, version, kind } = gvk;
const groupWithoutK8sIO = group.replace('.k8s.io', '').replace('rbac.authorization', 'rbac');
const k8sTypeName = `io.k8s.api.${groupWithoutK8sIO.toLowerCase()}.${version.toLowerCase()}.${kind.toLowerCase()}`;
const k8sSchema = kubernetesSchema.schema;
const matchingBuiltin = (k8sSchema.oneOf || [])
.map((s) => {
if (typeof s === 'boolean') {
return undefined;
}
return s._$ref || s.$ref;
})
.find((ref) => {
if (!ref) {
return false;
}
const lowercaseRef = ref.replace('_definitions.json#/definitions/', '').toLowerCase();
return lowercaseRef === k8sTypeName;
});
if (matchingBuiltin) {
const lastSlash = kubernetesSchemaURI.lastIndexOf('/');
const baseURL = lastSlash === -1 ? null : kubernetesSchemaURI.substring(0, lastSlash + 1);
return baseURL ? baseURL + matchingBuiltin : undefined;
}
return undefined;
}
/**
* Retrieve schema by auto-detecting the Kubernetes GroupVersionKind (GVK) from the document.
* If there is no definition for the GVK in the main kubernetes schema,
* the schema is then retrieved from the CRD catalog.
* Public for testing purpose, not part of the API.
* @param doc
* @param crdCatalogURI The URL of the CRD catalog to retrieve the schema from
*/
function autoDetectCustomResource(gvk, crdCatalogURI) {
const { group, version, kind } = gvk;
const groupWithoutK8sIO = group.replace('.k8s.io', '').replace('rbac.authorization', 'rbac');
const k8sTypeName = `io.k8s.api.${groupWithoutK8sIO.toLowerCase()}.${version.toLowerCase()}.${kind.toLowerCase()}`;
if (k8sTypeName.includes('openshift.io')) {
return `${crdCatalogURI}/openshift/v4.15-strict/${kind.toLowerCase()}_${group.toLowerCase()}_${version.toLowerCase()}.json`;
}
const schemaURL = `${crdCatalogURI}/${group.toLowerCase()}/${kind.toLowerCase()}_${version.toLowerCase()}.json`;
return schemaURL;
}
/**
* Retrieve the group, version and kind from the document.
* Public for testing purpose, not part of the API.
* @param doc
*/
function getGroupVersionKindFromDocument(doc) {
if (doc instanceof yamlParser07_1.SingleYAMLDocument) {
try {
const rootJSON = doc.root.internalNode.toJSON();
if (!rootJSON) {
return undefined;
}
const groupVersion = rootJSON['apiVersion'];
if (!groupVersion) {
return undefined;
}
const [group, version] = groupVersion.split('/');
if (!group || !version) {
return undefined;
}
const kind = rootJSON['kind'];
if (!kind) {
return undefined;
}
return { group, version, kind };
}
catch (error) {
console.error('Error parsing YAML document:', error);
return undefined;
}
}
return undefined;
}
//# sourceMappingURL=k8sSchemaUtil.js.map