-
Notifications
You must be signed in to change notification settings - Fork 281
/
Copy pathcrdUtil.ts
89 lines (79 loc) · 2.8 KB
/
crdUtil.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import { SingleYAMLDocument } from '../parser/yamlParser07';
import { JSONDocument } from '../parser/jsonParser07';
import { ResolvedSchema } from 'vscode-json-languageservice/lib/umd/services/jsonSchemaService';
import { JSONSchema } from 'vscode-json-languageservice/lib/umd/jsonSchema';
import { KUBERNETES_SCHEMA_URL } from '../utils/schemaUrls';
/**
* 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
* @param kubernetesSchema The main kubernetes schema, if it includes a definition for the GVK it will be used
*/
export function autoDetectKubernetesSchemaFromDocument(
doc: SingleYAMLDocument | JSONDocument,
crdCatalogURI: string,
kubernetesSchema: ResolvedSchema
): string | undefined {
const res = getGroupVersionKindFromDocument(doc);
if (!res) {
return undefined;
}
const { group, version, kind } = res;
if (!group || !version || !kind) {
return undefined;
}
const k8sSchema: JSONSchema = kubernetesSchema.schema;
let kubernetesBuildIns: string[] = k8sSchema.oneOf
.map((s) => {
if (typeof s === 'boolean') {
return undefined;
}
// @ts-ignore
return s._$ref;
})
.filter((ref) => ref)
.map((ref) => ref.replace('_definitions.json#/definitions/', '').toLowerCase());
const k8sTypeName = `io.k8s.api.${group.toLowerCase()}.${version.toLowerCase()}.${kind.toLowerCase()}`;
if (kubernetesBuildIns.includes(k8sTypeName)) {
return KUBERNETES_SCHEMA_URL;
}
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
*/
export function getGroupVersionKindFromDocument(
doc: SingleYAMLDocument | JSONDocument
): { group: string; version: string; kind: string } | undefined {
if (doc instanceof 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;
}