plugins: New static scanner and validator, with Thema slot support (#53754)

* coremodels: Convert plugin-metadata schema to a coremodel

* Newer cuetsy; try quoting field name

* Add slot definitions

* Start sketching out pfs package

* Rerun codegen with fixes, new cuetsy

* Catch up dashboard with new cuetsy

* Update to go1.18

* Use new vmuxers in thema

* Add slot system in Go

* Draft finished implementation of pfs

* Collapse slot pkg into coremodel dir; add PluginInfo

* Add the mux type on top of kernel

* Refactor plugin generator for extensibility

* Change models.cue package, numerous debugs

* Bring new output to parity with old

* Remove old plugin generation logic

* Misc tweaking

* Reintroduce generation of shared schemas

* Drop back to go1.17

* Add globbing to tsconfig exclude

* Introduce pfs test on existing testdata

* Make most existing testdata tests pass with pfs

* coremodels: Convert plugin-metadata schema to a coremodel

* Newer cuetsy; try quoting field name

* Add APIType control concept, regen pluginmeta

* Use proper numeric types for schema fields

* Make pluginmeta schema follow Go type breakdown

* More decomposition into distinct types

* Add test case for no plugin.json file

* Fix missing ref to #Dependencies

* Remove generated TS for pluginmeta

* Update dependencies, rearrange go.mod

* Regenerate without Model prefix

* Use updated thema loader; this is now runnable

* Skip app plugin with weird include

* Make plugin tree extractor reusable

* Split out slot lineage load/validate logic

* Add myriad tests for new plugin validation failures

* Add test for zip fixtures

* One last run of codegen

* Proper delinting

* Ensure validation order is deterministic

* Let there actually be sorting

* Undo reliance on builtIn field (#54009)

* undo builtIn reliance

* fix tests

Co-authored-by: Will Browne <wbrowne@users.noreply.github.com>
This commit is contained in:
sam boyer
2022-08-22 12:11:45 -04:00
committed by GitHub
parent 828497447a
commit 4d433084a5
85 changed files with 1775 additions and 479 deletions
@@ -0,0 +1,23 @@
package grafanaplugin
import (
"github.com/grafana/thema"
"github.com/grafana/grafana/pkg/framework/coremodel"
)
_dummy: coremodel.slots
Panel: thema.#Lineage & {
name: "disallowed_cue_import"
seqs: [
{
schemas: [
{
PanelOptions: {
foo: string
} @cuetsy(kind="interface")
},
]
},
]
}
@@ -0,0 +1,14 @@
{
"type": "panel",
"name": "Disallowed CUE import",
"id": "disallowed-import-panel",
"backend": true,
"state": "alpha",
"info": {
"description": "Test",
"author": {
"name": "Grafana Labs",
"url": "https://grafana.com"
}
}
}
+1 -1
View File
@@ -1,7 +1,7 @@
{
"type": "datasource",
"name": "Test",
"id": "test",
"id": "test-datasource",
"backend": true,
"executable": "test",
"state": "alpha",
@@ -1,7 +1,7 @@
{
"type": "datasource",
"name": "Test",
"id": "test",
"id": "test-datasource",
"backend": true,
"state": "alpha",
"info": {
@@ -1,7 +1,7 @@
{
"type": "datasource",
"name": "Test",
"id": "test",
"id": "test-datasource",
"backend": true,
"executable": "test",
"state": "alpha",
@@ -1,7 +1,7 @@
{
"type": "datasource",
"name": "Test",
"id": "test",
"id": "test-datasource",
"backend": true,
"executable": "test",
"state": "alpha",
@@ -1,7 +1,7 @@
{
"type": "datasource",
"name": "Test",
"id": "test",
"id": "test-datasource",
"backend": true,
"info": {
"description": "Test",
+18
View File
@@ -0,0 +1,18 @@
package grafanaplugin
import "github.com/grafana/thema"
Panel: thema.#Lineage & {
name: "doesnamatch"
seqs: [
{
schemas: [
{
PanelOptions: {
foo: string
} @cuetsy(kind="interface")
},
]
},
]
}
+14
View File
@@ -0,0 +1,14 @@
{
"type": "panel",
"name": "Slot impl testing",
"id": "mismatch-panel",
"backend": true,
"state": "alpha",
"info": {
"description": "Test",
"author": {
"name": "Grafana Labs",
"url": "https://grafana.com"
}
}
}
@@ -0,0 +1,16 @@
package grafanaplugin
import "github.com/grafana/thema"
Query: thema.#Lineage & {
name: "missing_slot_impl"
seqs: [
{
schemas: [
{
foo: string
},
]
},
]
}
@@ -0,0 +1,14 @@
{
"type": "datasource",
"name": "Missing slot impl",
"id": "missing-slot-datasource",
"backend": true,
"state": "alpha",
"info": {
"description": "Test",
"author": {
"name": "Grafana Labs",
"url": "https://grafana.com"
}
}
}
@@ -0,0 +1,18 @@
package grafanaplugin
import "github.com/grafana/thema"
Panel: thema.#Lineage & {
name: "mismatch"
seqs: [
{
schemas: [
{
PanelOptions: {
foo: string
} @cuetsy(kind="interface")
},
]
},
]
}
@@ -0,0 +1,14 @@
{
"type": "panel",
"name": "ID/Name mismatch",
"id": "name-mismatch-panel",
"backend": true,
"state": "alpha",
"info": {
"description": "Test",
"author": {
"name": "Grafana Labs",
"url": "https://grafana.com"
}
}
}
@@ -7,22 +7,23 @@ Hash: SHA512
"signatureType": "grafana",
"signedByOrg": "grafana",
"signedByOrgName": "Grafana Labs",
"plugin": "test-ds",
"plugin": "test-datasource",
"version": "1.0.0",
"time": 1629461930434,
"time": 1661172777367,
"keyId": "7e4d0c6a708866e7",
"files": {
"plugin.json": "64e98031f30cfada473e0ad4b989ac10cd0c86844aab8c0d3fc36d8a9537a0b8",
"plugin.json": "a029469ace740e9502bfb0d40924d1cccae73d0b18adcd8f1ceb7f17bf36beb8",
"nested/plugin.json": "e64abd35cd211e0e4682974ad5cdd1be7a0b7cd24951d302a16d9e2cb6cefea4"
}
}
-----BEGIN PGP SIGNATURE-----
Version: OpenPGP.js v4.10.1
Version: OpenPGP.js v4.10.10
Comment: https://openpgpjs.org
wqIEARMKAAYFAmEfnaoACgkQfk0ManCIZufwYgIJAZULZ72BKYehVw362aOJ
IkUhCaIceQT6rSmWw60Ksxs8xkeCebMPfuxm6xqpvoquVmD2zIirCFUXE41M
SQBys7/aAgkBaaVZvVPLUMYHIGNQXQ0wJ0j6JGn5Mn25GH4lH4vttaCFpQmx
zwV8J/s7Ho612fU1ijH/nFM97I4nfxonQUEyEbA=
=7sr3
wrgEARMKAAYFAmMDfCkAIQkQfk0ManCIZucWIQTzOyW2kQdOhGNlcPN+TQxq
cIhm56w5AgkBeX3H13KSFfSs6i6aJLOIPyqYICT9EQWKxmZIz4vlgnOBOvdA
cf5jtG/CFYikBAHN6PAH6/Jir+4017w1JNHNtxICBj5xERqPkjb3GqT1sNb3
MJizG0LSveo6dRaap8uC4VPbubiUa7qGu6LTEi/8kpOemMNOLHBI+2/GlY3B
i8zqeBLU
=lRFr
-----END PGP SIGNATURE-----
@@ -1,7 +1,7 @@
{
"type": "datasource",
"name": "Parent",
"id": "test-ds",
"id": "test-datasource",
"backend": true,
"info": {
"description": "Parent plugin",
View File
@@ -10,22 +10,22 @@ Hash: SHA512
"rootUrls": [
"https://dev.grafana.com/"
],
"plugin": "test",
"plugin": "test-datasource",
"version": "1.0.0",
"time": 1657888677250,
"time": 1661173657946,
"keyId": "7e4d0c6a708866e7",
"files": {
"plugin.json": "2bb467c0bfd6c454551419efe475b8bf8573734e73c7bab52b14842adb62886f"
"plugin.json": "203ef4a613c5693c437a665cd67f95e2756a0f71b336b2ffb265db7c180d0b19"
}
}
-----BEGIN PGP SIGNATURE-----
Version: OpenPGP.js v4.10.10
Comment: https://openpgpjs.org
wrgEARMKAAYFAmLRX6UAIQkQfk0ManCIZucWIQTzOyW2kQdOhGNlcPN+TQxq
cIhm5wu9Agjhh5II2OyqsYDUqajO9KtwMzAnEMwaT5Kj0oCOsjJruoT/jLz6
HO7ioenfCwqNxaJswuFkvpN+5BnrrbIwXDo1mgIJARFtKuRg1t4TK2DPcMiQ
IiEWNrFGK0jCFaofroH1sGnhjNqUy6JAIUQlUn17BHwiJdBqpsihW1HvPhMa
8KOdLWED
=D70r
wrgEARMKAAYFAmMDf5oAIQkQfk0ManCIZucWIQTzOyW2kQdOhGNlcPN+TQxq
cIhm54/fAgkBVr9FXILsku+PsG86pZbxSbB/5/OeDsoqq9vJ30R3yaBYJC0N
tcS1PtWPzc3yMqJY1zi5pem0WfmYdH3j++NqB3QCCIUz1eAjgbilvIvoyj/j
Ia9Vcje1c3xApMFAeD4DdUBgFljAUFzz48IjZacjSNFm+gaNPhWJzYmo83wz
VqEbGL1A
=SzNa
-----END PGP SIGNATURE-----
@@ -1,7 +1,7 @@
{
"type": "datasource",
"name": "Test",
"id": "test",
"id": "test-datasource",
"backend": true,
"executable": "test",
"state": "alpha",
@@ -0,0 +1,23 @@
package grafanaplugin
import "github.com/grafana/thema"
Panel: thema.#Lineage & {
joinSchema: {
PanelOptions: {...}
PanelFieldConfig: string
}
name: "panel_conflicting_joinschema"
seqs: [
{
schemas: [
{
PanelOptions: {
foo: string
} @cuetsy(kind="interface")
PanelFieldConfig: string
},
]
},
]
}
@@ -0,0 +1,14 @@
{
"type": "panel",
"name": "Slot impl testing",
"id": "panel-conflicting-joinschema",
"backend": true,
"state": "alpha",
"info": {
"description": "Test",
"author": {
"name": "Grafana Labs",
"url": "https://grafana.com"
}
}
}
@@ -0,0 +1,19 @@
package grafanaplugin
import "github.com/grafana/thema"
Panel: thema.#Lineage & {
name: "panel_does_not_follow_slot_joinschema"
seqs: [
{
schemas: [
{
PanelOptions: {
foo: string
} @cuetsy(kind="interface")
PanelFieldConfig: string
},
]
},
]
}
@@ -0,0 +1,14 @@
{
"type": "panel",
"name": "Slot impl testing",
"id": "panel-does-not-follow-slot-joinschema",
"backend": true,
"state": "alpha",
"info": {
"description": "Test",
"author": {
"name": "Grafana Labs",
"url": "https://grafana.com"
}
}
}
@@ -1,7 +1,7 @@
{
"type": "datasource",
"name": "Test",
"id": "test",
"id": "test-datasource",
"backend": true,
"state": "alpha",
"info": {
@@ -0,0 +1,34 @@
package grafanaplugin
import "github.com/grafana/thema"
Query: thema.#Lineage & {
name: "valid_model_datasource"
seqs: [
{
schemas: [
{
foo: string
},
]
},
]
}
DSOptions: thema.#Lineage & {
name: "valid_model_datasource"
seqs: [
{
schemas: [
{
Options: {
foo: string
}
SecureOptions: {
bar: string
}
},
]
},
]
}
@@ -0,0 +1,14 @@
{
"type": "datasource",
"name": "Datasource models valid",
"id": "valid-model-datasource",
"backend": true,
"state": "alpha",
"info": {
"description": "Test",
"author": {
"name": "Grafana Labs",
"url": "https://grafana.com"
}
}
}
@@ -0,0 +1,18 @@
package grafanaplugin
import "github.com/grafana/thema"
Panel: thema.#Lineage & {
name: "valid_model_panel"
seqs: [
{
schemas: [
{
PanelOptions: {
foo: string
} @cuetsy(kind="interface")
},
]
},
]
}
@@ -0,0 +1,14 @@
{
"type": "panel",
"name": "Panel models valid",
"id": "valid-model-panel",
"backend": true,
"state": "alpha",
"info": {
"description": "Test",
"author": {
"name": "Grafana Labs",
"url": "https://grafana.com"
}
}
}
@@ -8,23 +8,24 @@ Hash: SHA512
"signedByOrg": "willbrowne",
"signedByOrgName": "Will Browne",
"rootUrls": [
"http://localhost:3000/grafana/"
"http://localhost:3000/grafana"
],
"plugin": "test",
"plugin": "test-datasource",
"version": "1.0.0",
"time": 1623165794939,
"time": 1661171981629,
"keyId": "7e4d0c6a708866e7",
"files": {
"plugin.json": "2bb467c0bfd6c454551419efe475b8bf8573734e73c7bab52b14842adb62886f"
"plugin.json": "203ef4a613c5693c437a665cd67f95e2756a0f71b336b2ffb265db7c180d0b19"
}
}
-----BEGIN PGP SIGNATURE-----
Version: OpenPGP.js v4.10.1
Version: OpenPGP.js v4.10.10
Comment: https://openpgpjs.org
wqEEARMKAAYFAmC/i2MACgkQfk0ManCIZudCEgII80waYmySwVuB2cdeU3Vy
FvYrhViYYimvTy5EQbDfC955UpHphcr4V5S+09se7D2bK8XZ/MYufnUp9QIU
gOxCDrkCCQHTQ/aWxt8JAHGG/eoydKQEeAc9aFJyphdX57qXHVkAjvLzY5aO
y9UltPQKOAN/soDra2m39VUf6DBi9K/sXfjwaA==
=cd6n
wrcEARMKAAYFAmMDeQ0AIQkQfk0ManCIZucWIQTzOyW2kQdOhGNlcPN+TQxq
cIhm5ygmAgiUFIfZrpxCa5VajERXgejFRwGrWYILWXmmXWC4vqHiQaFEE1Ef
DtLz0JcdEMhvhydD+efJbWuUcv7fEMWMv6k0YAIGLG4xVsef4OhnfMYKjRBf
Obc4/RuzqbjLg04Z9XDq6gAY06NESYscSj+Vy3rKNo0IiVnjrm9qGvZmSqRx
sLyae5M=
=ZAe8
-----END PGP SIGNATURE-----
@@ -1,7 +1,7 @@
{
"type": "datasource",
"name": "Test",
"id": "test",
"id": "test-datasource",
"backend": true,
"executable": "test",
"state": "alpha",
@@ -10,21 +10,22 @@ Hash: SHA512
"rootUrls": [
"http://localhost:3000/"
],
"plugin": "test",
"plugin": "test-datasource",
"version": "1.0.0",
"time": 1605807018050,
"time": 1661171417046,
"keyId": "7e4d0c6a708866e7",
"files": {
"plugin.json": "2bb467c0bfd6c454551419efe475b8bf8573734e73c7bab52b14842adb62886f"
"plugin.json": "203ef4a613c5693c437a665cd67f95e2756a0f71b336b2ffb265db7c180d0b19"
}
}
-----BEGIN PGP SIGNATURE-----
Version: OpenPGP.js v4.10.1
Version: OpenPGP.js v4.10.10
Comment: https://openpgpjs.org
wqIEARMKAAYFAl+2q6oACgkQfk0ManCIZudmzwIJAXWz58cd/91rTXszKPnE
xbVEvERCbjKTtPBQBNQyqEvV+Ig3MuBSNOVy2SOGrMsdbS6lONgvgt4Cm+iS
wV+vYifkAgkBJtg/9DMB7/iX5O0h49CtSltcpfBFXlGqIeOwRac/yENzRzAA
khdr/tZ1PDgRxMqB/u+Vtbpl0xSxgblnrDOYMSI=
=rLIE
wrgEARMKAAYFAmMDdtkAIQkQfk0ManCIZucWIQTzOyW2kQdOhGNlcPN+TQxq
cIhm577/AgkBnbauM7s/8jLrdJvr+b9B2ZK7EipwI9GFClBdGfxhBzw/QcHS
ete9DAB0j9V5ilShlg3O4gmbiFUFUKGWByHt/VUCB3TXblS7cf5kJFjB9v0r
fv5a8NfV8x8ao/WoKTmXRUB7HSScOvb/3KmkNqzcHtZPQS1T0P6l9EUA1QT1
l+GB3Wdq
=pe3h
-----END PGP SIGNATURE-----
@@ -1,7 +1,7 @@
{
"type": "datasource",
"name": "Test",
"id": "test",
"id": "test-datasource",
"backend": true,
"executable": "test",
"state": "alpha",
@@ -7,21 +7,22 @@ Hash: SHA512
"signatureType": "grafana",
"signedByOrg": "grafana",
"signedByOrgName": "Grafana Labs",
"plugin": "test",
"plugin": "test-datasource",
"version": "1.0.0",
"time": 1605807330546,
"time": 1661171059101,
"keyId": "7e4d0c6a708866e7",
"files": {
"plugin.json": "2bb467c0bfd6c454551419efe475b8bf8573734e73c7bab52b14842adb62886f"
"plugin.json": "203ef4a613c5693c437a665cd67f95e2756a0f71b336b2ffb265db7c180d0b19"
}
}
-----BEGIN PGP SIGNATURE-----
Version: OpenPGP.js v4.10.1
Version: OpenPGP.js v4.10.10
Comment: https://openpgpjs.org
wqEEARMKAAYFAl+2rOIACgkQfk0ManCIZudNOwIJAT8FTzwnRFCSLTOaR3F3
2Fh96eRbghokXcQG9WqpQAg8ZiVfGXeWWRNtV+nuQ9VOZOTO0BovWLuMkym2
ci8ABpWOAgd46LkGn3Dd8XVnGmLI6UPqHAXflItOrCMRiGcYJn5PxP1aCz8h
D0JoNI9TIKrhMtM4voU3Qhf3mIOTHueuDNS48w==
=mu2j
wrgEARMKAAYFAmMDdXMAIQkQfk0ManCIZucWIQTzOyW2kQdOhGNlcPN+TQxq
cIhm54zLAgdfVimeut6Gw9MrIACBZUSH0ht9p9j+iG6MDjpmEFIpqVJrem6f
8wBv0/kmYU3LV9MWyPuUeRfBdccjQKSjEXlfEAIJAVmut9LcSKIykhWuQA+7
VMVvJPXzlPkeoYsGYvzAlxh8i2UomCU15UChe62Gzq5V5HgGYkX5layIb5XX
y2Pio0lc
=/TR0
-----END PGP SIGNATURE-----
@@ -1,7 +1,7 @@
{
"type": "datasource",
"name": "Test",
"id": "test",
"id": "test-datasource",
"backend": true,
"executable": "test",
"state": "alpha",
@@ -0,0 +1,31 @@
package grafanaplugin
import "github.com/grafana/thema"
Query: thema.#Lineage & {
name: "wrong_slot_panel"
seqs: [
{
schemas: [
{
foo: string
},
]
},
]
}
Panel: thema.#Lineage & {
name: "wrong_slot_panel"
seqs: [
{
schemas: [
{
PanelOptions: {
foo: string
} @cuetsy(kind="interface")
},
]
},
]
}
@@ -0,0 +1,14 @@
{
"type": "panel",
"name": "Wrong slot for type",
"id": "wrong-slot-panel",
"backend": true,
"state": "alpha",
"info": {
"description": "Test",
"author": {
"name": "Grafana Labs",
"url": "https://grafana.com"
}
}
}