Compare commits
910 Commits
v11.5.5
...
jackw/rspa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a19b14a54a | ||
|
|
48793907a0 | ||
|
|
c611c0bbd4 | ||
|
|
1a492a0eb8 | ||
|
|
8df4243a8c | ||
|
|
156e160cfa | ||
|
|
8d03ea95af | ||
|
|
5174fd803e | ||
|
|
79f13e6280 | ||
|
|
7166eb8fc4 | ||
|
|
b9392dd8a9 | ||
|
|
3dfd0b923c | ||
|
|
3b850fa1df | ||
|
|
ed879eef40 | ||
|
|
eafb09b302 | ||
|
|
e955b3c864 | ||
|
|
ecaba8b054 | ||
|
|
e764556aba | ||
|
|
6c31fe645c | ||
|
|
0402709e68 | ||
|
|
a301c22e2b | ||
|
|
f90c4b9cad | ||
|
|
f7d1a86122 | ||
|
|
bbda8c6b6b | ||
|
|
32af00eff9 | ||
|
|
4df398c084 | ||
|
|
61d959d04b | ||
|
|
aceda85a4d | ||
|
|
9df6412e92 | ||
|
|
ff7ba54cbc | ||
|
|
78ef9fd9d9 | ||
|
|
7a6f4ced06 | ||
|
|
3bb3a74ac1 | ||
|
|
27837ee937 | ||
|
|
67722de343 | ||
|
|
29afe7d2cc | ||
|
|
39b424b8a7 | ||
|
|
60fa83ea53 | ||
|
|
84d22e176b | ||
|
|
187a18ea25 | ||
|
|
d4fdffc387 | ||
|
|
e9b2f69137 | ||
|
|
8edfff1bba | ||
|
|
2014d27def | ||
|
|
c9250c9135 | ||
|
|
f15c961a90 | ||
|
|
855eadcabd | ||
|
|
497491846e | ||
|
|
f535a7804f | ||
|
|
a05ba6ff41 | ||
|
|
6eeb28e312 | ||
|
|
ea788975e0 | ||
|
|
e5b49a406f | ||
|
|
89e85c1592 | ||
|
|
9494e6eb37 | ||
|
|
b89fd287c7 | ||
|
|
77fd572973 | ||
|
|
cd30f3839d | ||
|
|
30ae434a2e | ||
|
|
39db59fc73 | ||
|
|
589340e03c | ||
|
|
dc5602bad9 | ||
|
|
cbae35c28b | ||
|
|
e343cb5ac9 | ||
|
|
6bd1041cda | ||
|
|
d0394bfa7e | ||
|
|
861686adaa | ||
|
|
37ee1c427d | ||
|
|
c522a5b13b | ||
|
|
4d7b9a3c77 | ||
|
|
3a8a24e662 | ||
|
|
b9034f413e | ||
|
|
9cff383830 | ||
|
|
23a657a72d | ||
|
|
c291ec7ba9 | ||
|
|
196a73ec72 | ||
|
|
af8cab9210 | ||
|
|
101c590f34 | ||
|
|
b814f1628f | ||
|
|
9e3872f8dd | ||
|
|
1856d47e47 | ||
|
|
d092998927 | ||
|
|
ba3a90d8fd | ||
|
|
9d68c4f665 | ||
|
|
cf2a7687e0 | ||
|
|
b1222be02e | ||
|
|
f1b4678012 | ||
|
|
da66060f75 | ||
|
|
dc3de1a1d5 | ||
|
|
d8b26b0a31 | ||
|
|
12bb50f97f | ||
|
|
7f20495289 | ||
|
|
1c2f4e35bf | ||
|
|
c963032915 | ||
|
|
e2081c3e0c | ||
|
|
3b694785f3 | ||
|
|
964f3d0cad | ||
|
|
d81c4b3c42 | ||
|
|
ac412e6859 | ||
|
|
4e976fc277 | ||
|
|
75320990db | ||
|
|
5aeaa18ac2 | ||
|
|
02118cc6aa | ||
|
|
eeadb7e771 | ||
|
|
19777ba3e9 | ||
|
|
5315b4fd2d | ||
|
|
b58b5b5768 | ||
|
|
2bdeb727cf | ||
|
|
155492c8a5 | ||
|
|
6e4c1a57c1 | ||
|
|
90eb499b78 | ||
|
|
d719e6c621 | ||
|
|
0dab384826 | ||
|
|
aeb57f671b | ||
|
|
30939fd0e9 | ||
|
|
1018aec6bc | ||
|
|
5a74a1a0f6 | ||
|
|
527fc3bb21 | ||
|
|
7edcde6365 | ||
|
|
9dd75aee32 | ||
|
|
71f97f380d | ||
|
|
9ad6653871 | ||
|
|
afe8b08a48 | ||
|
|
a58564a35e | ||
|
|
be60ef0500 | ||
|
|
a69fac6e16 | ||
|
|
1c7a758127 | ||
|
|
3c56e32b0c | ||
|
|
1b1954de28 | ||
|
|
ae9837b793 | ||
|
|
6db155649c | ||
|
|
0b4c622df8 | ||
|
|
95ee93a0d8 | ||
|
|
293f514854 | ||
|
|
5a6d2f2e49 | ||
|
|
8a8e47fcea | ||
|
|
fbf96916aa | ||
|
|
df64dd0762 | ||
|
|
2dee9ccbbc | ||
|
|
2b2b19478a | ||
|
|
0a88cb528a | ||
|
|
a34e7e176d | ||
|
|
3dcd885644 | ||
|
|
f9c329bbd1 | ||
|
|
62e06cfac8 | ||
|
|
d1dee968c3 | ||
|
|
e60e217a23 | ||
|
|
950726a3c5 | ||
|
|
c556f20627 | ||
|
|
3cc4320aa9 | ||
|
|
e2a101cde3 | ||
|
|
21861867c1 | ||
|
|
d3de9dbce6 | ||
|
|
cfc529cb03 | ||
|
|
2b054d4154 | ||
|
|
f6f50f7693 | ||
|
|
6e00954bb1 | ||
|
|
1f6142dd8f | ||
|
|
a1e59a92b0 | ||
|
|
a9b4b1e5be | ||
|
|
983829e47b | ||
|
|
ee0a1391df | ||
|
|
a5c8b5ed83 | ||
|
|
91242340c1 | ||
|
|
2f329c211d | ||
|
|
33b48f7c6e | ||
|
|
b44b82606a | ||
|
|
8e436fc473 | ||
|
|
2b4e1f3c51 | ||
|
|
99c8d4b0c6 | ||
|
|
eb4c428d4e | ||
|
|
a0701a42f1 | ||
|
|
aca024bcbb | ||
|
|
9593e51da7 | ||
|
|
9b37e9249a | ||
|
|
d199c33d7e | ||
|
|
df84d928e2 | ||
|
|
ab74852fc9 | ||
|
|
ccb442558f | ||
|
|
a5355fd66c | ||
|
|
b6ea06f259 | ||
|
|
6d374a3d7f | ||
|
|
53ae85ca57 | ||
|
|
c15c9f8af6 | ||
|
|
a8b98ded66 | ||
|
|
d1b4162a33 | ||
|
|
f7588376df | ||
|
|
28f21e0a0d | ||
|
|
6da6660def | ||
|
|
4cac3158c7 | ||
|
|
79bd3ffd8c | ||
|
|
8a9f6416d2 | ||
|
|
14c8eb2373 | ||
|
|
8c0e087ce2 | ||
|
|
7234a17d1d | ||
|
|
bbe21bb1d2 | ||
|
|
43d7d00247 | ||
|
|
5118e82e8c | ||
|
|
e3cb73301e | ||
|
|
6ee3c71ffe | ||
|
|
e17fd5e8ad | ||
|
|
bfa4fa3c68 | ||
|
|
a1dacc24b9 | ||
|
|
9bdacf3833 | ||
|
|
d87ef806f0 | ||
|
|
d48802cdfb | ||
|
|
cbe5741096 | ||
|
|
cfb26f2a4b | ||
|
|
70b86eeb6d | ||
|
|
b0dd6e900a | ||
|
|
9f77c86b21 | ||
|
|
e5154ce799 | ||
|
|
6eaf702e96 | ||
|
|
b6c0db31d9 | ||
|
|
f8efdaf88c | ||
|
|
f2d34254d3 | ||
|
|
e4ef71b78e | ||
|
|
63216a3e6e | ||
|
|
7092fd269d | ||
|
|
4e48b7557c | ||
|
|
0152f414f0 | ||
|
|
27ece859e7 | ||
|
|
7dee4d1808 | ||
|
|
55e7c4ae6d | ||
|
|
1b8db233a7 | ||
|
|
dec07c4c34 | ||
|
|
02caf915a5 | ||
|
|
68700e3d7d | ||
|
|
30abff9998 | ||
|
|
9697a699f2 | ||
|
|
42170ad23a | ||
|
|
2518012569 | ||
|
|
7c8fddc729 | ||
|
|
390b5eb6d4 | ||
|
|
afab71e28c | ||
|
|
6723159b12 | ||
|
|
00155abf1b | ||
|
|
acc1521929 | ||
|
|
95e61f63f7 | ||
|
|
45775dd6ad | ||
|
|
f5c049012b | ||
|
|
bce05cd48d | ||
|
|
378bb6ea3f | ||
|
|
196029f287 | ||
|
|
7e11e604c7 | ||
|
|
bf27e6d3ed | ||
|
|
79d7e11fa4 | ||
|
|
f5d8f42635 | ||
|
|
7b48670104 | ||
|
|
7c9f47ac67 | ||
|
|
0bd4e3bda2 | ||
|
|
bf413643c8 | ||
|
|
97109b36e3 | ||
|
|
7ae8058c8b | ||
|
|
9ce6c69996 | ||
|
|
be42685852 | ||
|
|
f607bcd43f | ||
|
|
0beb7e668b | ||
|
|
158c5443b5 | ||
|
|
53030e7960 | ||
|
|
dfaa12b800 | ||
|
|
9d7a4a53e4 | ||
|
|
9fbb0b6636 | ||
|
|
6af67197a7 | ||
|
|
a412394a14 | ||
|
|
882b993496 | ||
|
|
6e748a9ee7 | ||
|
|
c43517d278 | ||
|
|
e815a2850e | ||
|
|
a51e785bc1 | ||
|
|
4b9fee61a8 | ||
|
|
ccb9cab131 | ||
|
|
e291140be3 | ||
|
|
6dc98dbbcc | ||
|
|
9da423045e | ||
|
|
d196b789e2 | ||
|
|
d62c490af5 | ||
|
|
d16f2315a4 | ||
|
|
74b2b5fb19 | ||
|
|
8e3327a446 | ||
|
|
c8609b8a61 | ||
|
|
f4426e22bf | ||
|
|
a9ce930634 | ||
|
|
2b3ccfe5b9 | ||
|
|
677060862c | ||
|
|
1467d4b3e3 | ||
|
|
ccb0e9222a | ||
|
|
011301f06f | ||
|
|
f8509273cb | ||
|
|
0035ed8a5e | ||
|
|
126396399e | ||
|
|
1bf53e7a5f | ||
|
|
05ea450dd2 | ||
|
|
21bfdd445f | ||
|
|
4c52abb6b4 | ||
|
|
f1eac34b54 | ||
|
|
ae33d49036 | ||
|
|
d3ce9e1fe2 | ||
|
|
98e3237ce2 | ||
|
|
57e30633e9 | ||
|
|
52db2070a0 | ||
|
|
d64f41afdc | ||
|
|
4e6bdce41c | ||
|
|
9fc82faea7 | ||
|
|
fde475e3d9 | ||
|
|
7d3a77a45c | ||
|
|
e05413dcc4 | ||
|
|
0916994d0a | ||
|
|
d5f1f4eb5c | ||
|
|
f89da88f0f | ||
|
|
36275a5510 | ||
|
|
495aa65c6e | ||
|
|
f7d476e408 | ||
|
|
0fe4b15d00 | ||
|
|
69e4d8468b | ||
|
|
364559e856 | ||
|
|
8e10ee9056 | ||
|
|
b7b2e2bbaa | ||
|
|
33b11d5c76 | ||
|
|
6787cdccb9 | ||
|
|
6200361f36 | ||
|
|
d58dec7951 | ||
|
|
92bb51bdda | ||
|
|
130d268b51 | ||
|
|
a93664ff3d | ||
|
|
0ca1febb77 | ||
|
|
39d94eabcd | ||
|
|
64800f293e | ||
|
|
6d159b6240 | ||
|
|
bf1174cfdc | ||
|
|
d53b269455 | ||
|
|
665974e751 | ||
|
|
095593c018 | ||
|
|
c4d0114376 | ||
|
|
39a6d2e586 | ||
|
|
f51571db5d | ||
|
|
bea62aa615 | ||
|
|
5ad31ebe39 | ||
|
|
17e21bff97 | ||
|
|
7ebc81fbbf | ||
|
|
f9c4d3edce | ||
|
|
68f1730461 | ||
|
|
6eac07c3a7 | ||
|
|
ff926c5ac5 | ||
|
|
87bb7c3947 | ||
|
|
3fd1b67381 | ||
|
|
e74cf72d99 | ||
|
|
b16e290444 | ||
|
|
bb15f24dcd | ||
|
|
00bcb61382 | ||
|
|
eb2f8182c0 | ||
|
|
cfae9d20d2 | ||
|
|
1f0ff19471 | ||
|
|
4009433792 | ||
|
|
2efb120737 | ||
|
|
958d6e5e3a | ||
|
|
cd7c9f8666 | ||
|
|
6e7e389ee2 | ||
|
|
d06d646aa1 | ||
|
|
5d232daf0b | ||
|
|
c0f8d58079 | ||
|
|
0fced84796 | ||
|
|
73e3b04565 | ||
|
|
c94b8b78ae | ||
|
|
443cb092b4 | ||
|
|
0fa2d182d6 | ||
|
|
8ac9c47222 | ||
|
|
88c62cd828 | ||
|
|
46af49f907 | ||
|
|
5fe6479a10 | ||
|
|
9677f4b692 | ||
|
|
29fa6dfc8d | ||
|
|
ac41c19350 | ||
|
|
8a259ecafa | ||
|
|
66aec9ec1f | ||
|
|
6805c5283c | ||
|
|
807f94b2c7 | ||
|
|
f728b2df12 | ||
|
|
d96c1169c2 | ||
|
|
62aaec14b6 | ||
|
|
d6c1e3bb45 | ||
|
|
a18fa4af8f | ||
|
|
302e90b8f8 | ||
|
|
c3a55ab8cb | ||
|
|
489c5006b4 | ||
|
|
6496705120 | ||
|
|
e0151528a4 | ||
|
|
34b2cb5e02 | ||
|
|
39605a93ab | ||
|
|
30bf2bcde1 | ||
|
|
c85a175212 | ||
|
|
a0901456ae | ||
|
|
b636b81b16 | ||
|
|
2aa78139c4 | ||
|
|
d16374d339 | ||
|
|
4cd2ebe186 | ||
|
|
74e3beabd0 | ||
|
|
61f5f215ee | ||
|
|
8c0b812874 | ||
|
|
295c0afc35 | ||
|
|
f45265b5f7 | ||
|
|
e03656669a | ||
|
|
7d9896d07e | ||
|
|
e7902316a8 | ||
|
|
481f99b07f | ||
|
|
9693212475 | ||
|
|
a21265a7ad | ||
|
|
0be6e1bb86 | ||
|
|
d0703cfdbd | ||
|
|
a3eebd7157 | ||
|
|
3d3b781c19 | ||
|
|
2e5f0bf77b | ||
|
|
c3599d9236 | ||
|
|
7c15d33304 | ||
|
|
d699f023c2 | ||
|
|
9ae5552cab | ||
|
|
74b04a237d | ||
|
|
05f039d5ab | ||
|
|
f51eacef9a | ||
|
|
111f973242 | ||
|
|
95a19c21df | ||
|
|
39f212a965 | ||
|
|
abc76f8aad | ||
|
|
3372720a52 | ||
|
|
71e78b49ab | ||
|
|
d062453c49 | ||
|
|
a2b1a85dc4 | ||
|
|
7190bfb0ca | ||
|
|
1458f5d0fb | ||
|
|
ec836f2760 | ||
|
|
3b231c433f | ||
|
|
bfdd00665b | ||
|
|
bda4deb20c | ||
|
|
58df80e542 | ||
|
|
e3d9b6cadf | ||
|
|
8ce8c1635f | ||
|
|
ce38eb3398 | ||
|
|
8e53e997a0 | ||
|
|
c8297599a9 | ||
|
|
415628a2c6 | ||
|
|
a95005eab5 | ||
|
|
3d19a778ba | ||
|
|
52aeae1342 | ||
|
|
f92945ac35 | ||
|
|
9189feeaf5 | ||
|
|
a066659e11 | ||
|
|
64e9c38b66 | ||
|
|
3589d9192d | ||
|
|
b683724bec | ||
|
|
7e1a8cb984 | ||
|
|
86a68627dd | ||
|
|
a92c8145f1 | ||
|
|
6392542db4 | ||
|
|
800c9fa3e6 | ||
|
|
1e3783cc11 | ||
|
|
f637ea225a | ||
|
|
4aa495fd02 | ||
|
|
2df05505db | ||
|
|
c2b44a5da1 | ||
|
|
408e3e91a8 | ||
|
|
9d5af95565 | ||
|
|
e61036271a | ||
|
|
0c120db84d | ||
|
|
3c0383f0d5 | ||
|
|
4b0f8d8363 | ||
|
|
2d491a9367 | ||
|
|
7007342704 | ||
|
|
8e9e3b8362 | ||
|
|
cf177776bf | ||
|
|
b820fd6bef | ||
|
|
83d4f6e868 | ||
|
|
3954a1948c | ||
|
|
1795a2b4e3 | ||
|
|
1048e23872 | ||
|
|
49bd8a608e | ||
|
|
7d4895c3c9 | ||
|
|
243ce03b93 | ||
|
|
8f60308e73 | ||
|
|
07601bee6f | ||
|
|
be9a7ce908 | ||
|
|
9f4e8ee206 | ||
|
|
0613ed1f11 | ||
|
|
d198fa1dd0 | ||
|
|
7883215c68 | ||
|
|
90c18099a5 | ||
|
|
9b37337f7b | ||
|
|
c0600969e0 | ||
|
|
f39517304b | ||
|
|
b4802e7116 | ||
|
|
03f89a1925 | ||
|
|
baaff6296f | ||
|
|
1087ed623f | ||
|
|
514da10f46 | ||
|
|
eb52af2b14 | ||
|
|
ebe2f442bd | ||
|
|
1444051b65 | ||
|
|
9b0078326a | ||
|
|
336449c169 | ||
|
|
6ea87802ed | ||
|
|
e6c2db82e0 | ||
|
|
a0f27caff2 | ||
|
|
978101b7a5 | ||
|
|
30c8ac7108 | ||
|
|
8e5a4560e8 | ||
|
|
8415059290 | ||
|
|
c7f83b7311 | ||
|
|
b06f83670e | ||
|
|
20f02ec12f | ||
|
|
6908f91428 | ||
|
|
745a25ad0a | ||
|
|
5cd1efb2d1 | ||
|
|
6ba18d05be | ||
|
|
d7070d11f6 | ||
|
|
b4b49fc587 | ||
|
|
055a63873b | ||
|
|
046754c3c2 | ||
|
|
f55686a0b4 | ||
|
|
a0bf9202f5 | ||
|
|
97f4a164d1 | ||
|
|
516bd0fd1c | ||
|
|
3ba0d8d4b5 | ||
|
|
dddfce2df7 | ||
|
|
721c2b0c7c | ||
|
|
04c84e06e5 | ||
|
|
3228ae727e | ||
|
|
056b5a7b08 | ||
|
|
92d5e82a33 | ||
|
|
abac53bd0a | ||
|
|
94a844977e | ||
|
|
d81b1bf803 | ||
|
|
6e8e320ace | ||
|
|
1fb1f8846f | ||
|
|
78848095ca | ||
|
|
0a805a2314 | ||
|
|
fe49b6279a | ||
|
|
0cef2b9ae7 | ||
|
|
05905a5069 | ||
|
|
058d3946b7 | ||
|
|
52a6c27d99 | ||
|
|
0bf31c14a7 | ||
|
|
8b9d4d1358 | ||
|
|
9d635edd0e | ||
|
|
af2c7a19d1 | ||
|
|
b1f39f4b8b | ||
|
|
f8e7e9e024 | ||
|
|
1cc9f8f0c2 | ||
|
|
ecc9b0c10c | ||
|
|
d2eac460cf | ||
|
|
8e6a868178 | ||
|
|
a66857dfbe | ||
|
|
a28328d764 | ||
|
|
f6fc39e71f | ||
|
|
58a279e109 | ||
|
|
8c2824cf3b | ||
|
|
a05f539dd2 | ||
|
|
9c7618160d | ||
|
|
58a3e0ae86 | ||
|
|
ae0de61b92 | ||
|
|
959a942b5c | ||
|
|
9949a56f3b | ||
|
|
3ed138543d | ||
|
|
acbdc1f415 | ||
|
|
4e703576b0 | ||
|
|
61c5b4a25e | ||
|
|
fd85ddf647 | ||
|
|
078ce6a289 | ||
|
|
82f457495a | ||
|
|
d71904cb27 | ||
|
|
32ae292334 | ||
|
|
7ebe599389 | ||
|
|
8954800d37 | ||
|
|
be8396cafa | ||
|
|
060182a3ba | ||
|
|
5c785e6101 | ||
|
|
cb43f4b696 | ||
|
|
6edd4f5a7c | ||
|
|
6e705ee67c | ||
|
|
2f2c6360cd | ||
|
|
b5ca30c69e | ||
|
|
30ee8b9813 | ||
|
|
a5c14db051 | ||
|
|
b4c13defa6 | ||
|
|
763f0bac90 | ||
|
|
1f19fc8e0f | ||
|
|
9bdeca8d10 | ||
|
|
1c66e0fe30 | ||
|
|
848ef72100 | ||
|
|
cc09f38421 | ||
|
|
e01d8ad5b5 | ||
|
|
c6ba0910b4 | ||
|
|
b0e74cf737 | ||
|
|
50b14c533c | ||
|
|
ae62b3817b | ||
|
|
571f20676d | ||
|
|
7720f0b64e | ||
|
|
a5916116b1 | ||
|
|
dde199f684 | ||
|
|
c5ff5d89df | ||
|
|
49f8359ce5 | ||
|
|
53cc790180 | ||
|
|
abe2a5370d | ||
|
|
e94c9f733b | ||
|
|
a2097fbc2f | ||
|
|
de1df2f4e9 | ||
|
|
d5d8abcd64 | ||
|
|
8f3fd8f91d | ||
|
|
ead8236cec | ||
|
|
629b20700c | ||
|
|
394d081df2 | ||
|
|
103a8f0793 | ||
|
|
12bda63871 | ||
|
|
84da64462e | ||
|
|
8e078315f0 | ||
|
|
0003efa285 | ||
|
|
25bb210ca3 | ||
|
|
154a57cd30 | ||
|
|
35a581a2ba | ||
|
|
d409853683 | ||
|
|
af663dadc7 | ||
|
|
4570f7319d | ||
|
|
92d6762a3a | ||
|
|
b3209b1e01 | ||
|
|
63a89afe00 | ||
|
|
888965023c | ||
|
|
361312bbd7 | ||
|
|
6284dd61ae | ||
|
|
d192a44469 | ||
|
|
33a53d170b | ||
|
|
437b7a565d | ||
|
|
eb2d276a42 | ||
|
|
33d82c43df | ||
|
|
e3ba96113c | ||
|
|
a9f62953df | ||
|
|
2dfb796f21 | ||
|
|
b07a39bb46 | ||
|
|
c787239252 | ||
|
|
7cb6845d44 | ||
|
|
df024793d8 | ||
|
|
5da15ccdc4 | ||
|
|
8c2a74bd74 | ||
|
|
a9f0e15778 | ||
|
|
6a205af5fe | ||
|
|
af640e2e50 | ||
|
|
3a94057ec8 | ||
|
|
fdbac6fb54 | ||
|
|
be40f531e6 | ||
|
|
572be19f76 | ||
|
|
e9d9b15295 | ||
|
|
d24e7c126d | ||
|
|
6b227bb374 | ||
|
|
75e7236687 | ||
|
|
a4ef1f76e4 | ||
|
|
192a81d07f | ||
|
|
59b246dbea | ||
|
|
ef3a53f85c | ||
|
|
ec9f59fe9e | ||
|
|
3993d691f4 | ||
|
|
a540c2fe7c | ||
|
|
b066a63131 | ||
|
|
7d2eb83cbd | ||
|
|
05015a57b3 | ||
|
|
5ca24fde02 | ||
|
|
f6202f59d4 | ||
|
|
a037c6f344 | ||
|
|
d39e57e836 | ||
|
|
89dd54a474 | ||
|
|
2716db4270 | ||
|
|
4e740d8410 | ||
|
|
e110338dce | ||
|
|
c62bc501d3 | ||
|
|
b79f1b2a29 | ||
|
|
b0347792cc | ||
|
|
83bbdbf8b6 | ||
|
|
750027d0a7 | ||
|
|
c4c934e0bd | ||
|
|
fc7db91bf1 | ||
|
|
723fa7ddf9 | ||
|
|
4fb7b47971 | ||
|
|
d476b65d34 | ||
|
|
25447ea93a | ||
|
|
db3dcd4f7d | ||
|
|
c862aa4d68 | ||
|
|
d740f9fc60 | ||
|
|
36fadf19d1 | ||
|
|
dfc565db8d | ||
|
|
1a634b0539 | ||
|
|
887e9fb5b5 | ||
|
|
7564ce8ce1 | ||
|
|
8de4b64047 | ||
|
|
1c8a7d8872 | ||
|
|
29d9d8cf51 | ||
|
|
a0e7569e4f | ||
|
|
daced46d27 | ||
|
|
88ab29f6ba | ||
|
|
974cec2936 | ||
|
|
a05bb05e60 | ||
|
|
003f0e5918 | ||
|
|
23f495d4cd | ||
|
|
d2d6dd2e5f | ||
|
|
51b4ac50aa | ||
|
|
5b8e6f8fa8 | ||
|
|
149bc74191 | ||
|
|
dd483fc17f | ||
|
|
5b5831ae34 | ||
|
|
9d30911107 | ||
|
|
3ae6e09fee | ||
|
|
2dfa0abfbe | ||
|
|
97db8b19c7 | ||
|
|
4b8e6b3401 | ||
|
|
88d5ae8153 | ||
|
|
5791115b0a | ||
|
|
28ad61ff6c | ||
|
|
20d25c6ad9 | ||
|
|
f1e9c5b1ef | ||
|
|
2622449718 | ||
|
|
45e2f95a41 | ||
|
|
1c858caec3 | ||
|
|
a03f897cd5 | ||
|
|
dccca0729f | ||
|
|
ad30ca2ccd | ||
|
|
97d8f68b70 | ||
|
|
b11d3bc045 | ||
|
|
2982d95a74 | ||
|
|
bd84fdad51 | ||
|
|
3bc9f10bb3 | ||
|
|
eaca8e501f | ||
|
|
5532d7007c | ||
|
|
12ae2a520c | ||
|
|
6f12b8e3a4 | ||
|
|
2fe510eb6f | ||
|
|
865e911e10 | ||
|
|
c7edbffd82 | ||
|
|
ee0129e8cf | ||
|
|
5a45f59573 | ||
|
|
36f850601f | ||
|
|
3177e33470 | ||
|
|
1740ee82ba | ||
|
|
c1eac9f997 | ||
|
|
e747350fee | ||
|
|
1b5eaebb6e | ||
|
|
83fffe83a2 | ||
|
|
13121ccf23 | ||
|
|
0f023e7039 | ||
|
|
d8b6ded101 | ||
|
|
9ce9ad1777 | ||
|
|
d91d729749 | ||
|
|
680e6bc1f8 | ||
|
|
b2d0359e72 | ||
|
|
bf1a0837af | ||
|
|
d3a27a8c73 | ||
|
|
c45aff1251 | ||
|
|
9801a5a943 | ||
|
|
8c90f30e68 | ||
|
|
2756bc9a87 | ||
|
|
52c95f77cd | ||
|
|
80a2d8ad34 | ||
|
|
4fb9f0a386 | ||
|
|
52c1a3dccd | ||
|
|
427a601980 | ||
|
|
15d0b139c7 | ||
|
|
863d56b7e1 | ||
|
|
cc3b3ccdef | ||
|
|
7329d2c34b | ||
|
|
0baf3a8f95 | ||
|
|
37b7776b21 | ||
|
|
c241ac57d8 | ||
|
|
cf19d6d4b7 | ||
|
|
c601d79889 | ||
|
|
80b8dd3fc8 | ||
|
|
95d4f83889 | ||
|
|
f96a2082d0 | ||
|
|
651430e34a | ||
|
|
63a68f3e99 | ||
|
|
27cdd25917 | ||
|
|
b3b044b54b | ||
|
|
c1364d6be6 | ||
|
|
55ec66c416 | ||
|
|
1f780fdce1 | ||
|
|
1e53ab609e | ||
|
|
dea2e41e9f | ||
|
|
1a2a284972 | ||
|
|
b309c5daed | ||
|
|
d346819d62 | ||
|
|
a61548c5b9 | ||
|
|
e33936398c | ||
|
|
8fabc66bd2 | ||
|
|
a6dffd7552 | ||
|
|
fb3a858726 | ||
|
|
414f8d14f4 | ||
|
|
f39c5bb45c | ||
|
|
798b32138d | ||
|
|
59184628e1 | ||
|
|
4f337b99d4 | ||
|
|
40baca699a | ||
|
|
55644faa9d | ||
|
|
7411663b74 | ||
|
|
ac94e81423 | ||
|
|
7ccc811203 | ||
|
|
feae06d81c | ||
|
|
2bce8c5e29 | ||
|
|
348c0319c4 | ||
|
|
bc6b7a4df6 | ||
|
|
1d7d658934 | ||
|
|
356b32008b | ||
|
|
67252dfa46 | ||
|
|
032f465ac6 | ||
|
|
7c04247d6f | ||
|
|
a0d1a197e3 | ||
|
|
f65e9fa9ab | ||
|
|
f9cc08a42d | ||
|
|
c5f14407cc | ||
|
|
5e23b2c07f | ||
|
|
f9a61e2eb2 | ||
|
|
17a09c28dd | ||
|
|
a08f406781 | ||
|
|
e019e34eb5 | ||
|
|
5a930e0ec6 | ||
|
|
6901bad03b | ||
|
|
c63c869bca | ||
|
|
f6194931f5 | ||
|
|
b4ec11e150 | ||
|
|
8e59f618c1 | ||
|
|
54440811b3 | ||
|
|
e96b5a68c4 | ||
|
|
c0b3932168 | ||
|
|
1eb45dd0f8 | ||
|
|
cff07c9fb6 | ||
|
|
106af5d0ee | ||
|
|
029edcb6be | ||
|
|
4386cfc984 | ||
|
|
019ee9c2d4 | ||
|
|
b532df36c4 | ||
|
|
a32eed1d13 | ||
|
|
3df1fa86ae | ||
|
|
d95484fba6 | ||
|
|
31deddafb6 | ||
|
|
4c0fa629da | ||
|
|
862c0ce9b5 | ||
|
|
70ddf9cb76 | ||
|
|
98e9f3a534 | ||
|
|
4936c53072 | ||
|
|
a3cdad25a3 | ||
|
|
2187a66f2b | ||
|
|
ee4016f4bc | ||
|
|
77f7ab27be | ||
|
|
4fcd529d0e | ||
|
|
76a7987427 | ||
|
|
7da6e48036 | ||
|
|
3641b28e84 | ||
|
|
d025523a8b | ||
|
|
cd46f1ddb9 | ||
|
|
f9f341e9c9 | ||
|
|
bab55a4cb8 | ||
|
|
fc90a446c6 | ||
|
|
b6fc695598 | ||
|
|
5d45af1110 | ||
|
|
d00592ffa0 | ||
|
|
8415089534 | ||
|
|
125fdc8f21 | ||
|
|
f142f12887 | ||
|
|
c03586dfe8 | ||
|
|
38927f0719 | ||
|
|
a290db6a7e | ||
|
|
e3e580edfa | ||
|
|
1dcff0a71f | ||
|
|
dfe0712955 | ||
|
|
79fc26ea87 | ||
|
|
ea6cb8f139 | ||
|
|
5aeaccadff | ||
|
|
7f04f66137 | ||
|
|
32790c6918 | ||
|
|
bbade6b011 | ||
|
|
a6eb8abd05 | ||
|
|
3f71a72c1a | ||
|
|
0d302a161a | ||
|
|
0fce8799eb | ||
|
|
2a08c9ed82 | ||
|
|
dbfc412ed8 | ||
|
|
e15fc984c3 | ||
|
|
69da0bb22c | ||
|
|
c5111b8132 | ||
|
|
3b8477dcda | ||
|
|
feb334cdbb | ||
|
|
f7e0710f53 | ||
|
|
e38bab43db | ||
|
|
1ff4053f03 | ||
|
|
ce0d986673 | ||
|
|
7151ea6abc | ||
|
|
b96a752db3 | ||
|
|
125a11ca99 | ||
|
|
3884c0e896 | ||
|
|
037570b9c8 | ||
|
|
7c87ff1b84 | ||
|
|
2594b4f7af | ||
|
|
0032e839ce | ||
|
|
6b5146651f | ||
|
|
7771768363 | ||
|
|
0b5b21548b | ||
|
|
70fb7b9545 | ||
|
|
ff032a61d5 | ||
|
|
5570a7e42e | ||
|
|
e45eb95812 | ||
|
|
33a91f22c0 | ||
|
|
dbd3bb7667 | ||
|
|
740cd22fe5 | ||
|
|
64617886d9 | ||
|
|
1281b0f094 | ||
|
|
5c49b6cf73 | ||
|
|
65f5a176a8 | ||
|
|
36d6fad421 |
@@ -86,6 +86,10 @@ module.exports = [
|
||||
importNames: ['Layout', 'HorizontalGroup', 'VerticalGroup'],
|
||||
message: 'Use Stack component instead.',
|
||||
},
|
||||
{
|
||||
group: ['@grafana/ui/src/*', '@grafana/runtime/src/*', '@grafana/data/src/*'],
|
||||
message: 'Import from the public export instead.',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
1454
.betterer.results
1454
.betterer.results
File diff suppressed because it is too large
Load Diff
@@ -5,6 +5,10 @@ GOPATH ?= $(shell go env GOPATH)
|
||||
GOBIN ?= $(firstword $(subst :, ,${GOPATH}))/bin
|
||||
GO ?= $(shell which go)
|
||||
|
||||
# Add this near the top of the file, after the initial variable definitions
|
||||
ifndef VARIABLES_MK
|
||||
VARIABLES_MK := 1
|
||||
|
||||
# Below generated variables ensure that every time a tool under each variable is invoked, the correct version
|
||||
# will be used; reinstalling only if needed.
|
||||
# For example for bra variable:
|
||||
@@ -23,6 +27,12 @@ $(BRA): $(BINGO_DIR)/bra.mod
|
||||
@echo "(re)installing $(GOBIN)/bra-v0.0.0-20200517080246-1e3013ecaff8"
|
||||
@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=bra.mod -o=$(GOBIN)/bra-v0.0.0-20200517080246-1e3013ecaff8 "github.com/unknwon/bra"
|
||||
|
||||
COG := $(GOBIN)/cog-v0.0.15
|
||||
$(COG): $(BINGO_DIR)/cog.mod
|
||||
@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
|
||||
@echo "(re)installing $(GOBIN)/cog-v0.0.15"
|
||||
@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=cog.mod -o=$(GOBIN)/cog-v0.0.15 "github.com/grafana/cog/cmd/cli"
|
||||
|
||||
CUE := $(GOBIN)/cue-v0.5.0
|
||||
$(CUE): $(BINGO_DIR)/cue.mod
|
||||
@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
|
||||
@@ -59,3 +69,4 @@ $(SWAGGER): $(BINGO_DIR)/swagger.mod
|
||||
@echo "(re)installing $(GOBIN)/swagger-v0.30.6-0.20240310114303-db51e79a0e37"
|
||||
@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=swagger.mod -o=$(GOBIN)/swagger-v0.30.6-0.20240310114303-db51e79a0e37 "github.com/go-swagger/go-swagger/cmd/swagger"
|
||||
|
||||
endif
|
||||
|
||||
5
.bingo/cog.mod
Normal file
5
.bingo/cog.mod
Normal file
@@ -0,0 +1,5 @@
|
||||
module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT
|
||||
|
||||
go 1.23.4
|
||||
|
||||
require github.com/grafana/cog v0.0.15 // cmd/cli
|
||||
@@ -1,11 +1,10 @@
|
||||
cuelabs.dev/go/oci/ociregistry v0.0.0-20240906074133-82eb438dd565 h1:R5wwEcbEZSBmeyg91MJZTxfd7WpBo2jPof3AYjRbxwY=
|
||||
cuelabs.dev/go/oci/ociregistry v0.0.0-20240906074133-82eb438dd565/go.mod h1:5A4xfTzHTXfeVJBU6RAUf+QrlfTCW+017q/QiW+sMLg=
|
||||
cuelang.org/go v0.11.1 h1:pV+49MX1mmvDm8Qh3Za3M786cty8VKPWzQ1Ho4gZRP0=
|
||||
cuelang.org/go v0.11.1/go.mod h1:PBY6XvPUswPPJ2inpvUozP9mebDVTXaeehQikhZPBz0=
|
||||
cuelang.org/go v0.11.0 h1:2af2nhipqlUHtXk2dtOP5xnMm1ObGvKqIsJUJL1sRE4=
|
||||
cuelang.org/go v0.11.0/go.mod h1:PBY6XvPUswPPJ2inpvUozP9mebDVTXaeehQikhZPBz0=
|
||||
github.com/cockroachdb/apd/v3 v3.2.1 h1:U+8j7t0axsIgvQUqthuNm82HIrYXodOV2iWLWtEaIwg=
|
||||
github.com/cockroachdb/apd/v3 v3.2.1/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/emicklei/proto v1.13.2 h1:z/etSFO3uyXeuEsVPzfl56WNgzcvIr42aQazXaQmFZY=
|
||||
github.com/emicklei/proto v1.13.2/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A=
|
||||
github.com/expr-lang/expr v1.16.9 h1:WUAzmR0JNI9JCiF0/ewwHB1gmcGw5wW7nWt8gc6PpCI=
|
||||
@@ -16,18 +15,16 @@ github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1
|
||||
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
|
||||
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
|
||||
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
|
||||
github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI=
|
||||
github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow=
|
||||
github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
|
||||
github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/grafana/codejen v0.0.4-0.20230321061741-77f656893a3d h1:hrXbGJ5jgp6yNITzs5o+zXq0V5yT3siNJ+uM8LGwWKk=
|
||||
github.com/grafana/codejen v0.0.4-0.20230321061741-77f656893a3d/go.mod h1:zmwwM/DRyQB7pfuBjTWII3CWtxcXh8LTwAYGfDfpR6s=
|
||||
github.com/grafana/cog v0.0.5 h1:BCa+10i3KvV+KMSQuxlN1DS9cZEwN+EAFc7ZmXqHxQE=
|
||||
github.com/grafana/cog v0.0.5/go.mod h1:lzetOuhGUl/JaSACiJoHvBokf9/fS6PEFaWZvnQu2vs=
|
||||
github.com/grafana/cog v0.0.14 h1:sBK89oSu9BK4S9l3G9ewVJnGYnNQJTHFBC/01DZDRZs=
|
||||
github.com/grafana/cog v0.0.14/go.mod h1:HwJbc60fZ+viayROClLGdDwO5w/JjBOpO9wjGnAfMLc=
|
||||
github.com/grafana/cog v0.0.15 h1:e2pMY+Hf2nS22HcKJuguEzl0BVmV9DSINwCfWt+dFZQ=
|
||||
github.com/grafana/cog v0.0.15/go.mod h1:jrS9indvWuDs60RHEZpLaAkmZdgyoLKMOEUT0jiB1t0=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
@@ -35,18 +32,12 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI=
|
||||
github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso=
|
||||
github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
|
||||
@@ -61,36 +52,35 @@ github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNH
|
||||
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
|
||||
github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s=
|
||||
github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/protocolbuffers/txtpbfmt v0.0.0-20241112170944-20d2c9ebc01d h1:HWfigq7lB31IeJL8iy7jkUmU/PG1Sr8jVGhS749dbUA=
|
||||
github.com/protocolbuffers/txtpbfmt v0.0.0-20241112170944-20d2c9ebc01d/go.mod h1:jgxiZysxFPM+iWKwQwPR+y+Jvo54ARd4EisXxKYpB5c=
|
||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4=
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
|
||||
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/yalue/merged_fs v1.3.0 h1:qCeh9tMPNy/i8cwDsQTJ5bLr6IRxbs6meakNE5O+wyY=
|
||||
github.com/yalue/merged_fs v1.3.0/go.mod h1:WqqchfVYQyclV2tnR7wtRhBddzBvLVR83Cjw9BKQw0M=
|
||||
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
|
||||
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI=
|
||||
golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs=
|
||||
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
|
||||
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
||||
golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE=
|
||||
golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8=
|
||||
golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw=
|
||||
golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE=
|
||||
golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
@@ -10,6 +10,8 @@ fi
|
||||
|
||||
BRA="${GOBIN}/bra-v0.0.0-20200517080246-1e3013ecaff8"
|
||||
|
||||
COG="${GOBIN}/cog-v0.0.15"
|
||||
|
||||
CUE="${GOBIN}/cue-v0.5.0"
|
||||
|
||||
DRONE="${GOBIN}/drone-v1.5.0"
|
||||
|
||||
356
.drone.yml
356
.drone.yml
File diff suppressed because it is too large
Load Diff
52
.github/CODEOWNERS
vendored
52
.github/CODEOWNERS
vendored
@@ -32,13 +32,13 @@
|
||||
/devenv/README.md @grafana/docs-grafana
|
||||
|
||||
# START Technical documentation
|
||||
/.vale.ini @grafana/docs-tooling
|
||||
# `make docs` procedure and related workflows are owned @grafana/docs-tooling. Slack #docs.
|
||||
/docs/ @grafana/docs-tooling
|
||||
|
||||
/docs/.codespellignore @grafana/docs-tooling
|
||||
/docs/sources/ @irenerl24
|
||||
|
||||
/docs/sources/alerting/ @brendamuir
|
||||
/docs/sources/alerting/ @JohnnyK-Grafana
|
||||
/docs/sources/dashboards/ @imatwawana
|
||||
/docs/sources/datasources/ @lwandz13
|
||||
/docs/sources/panels-visualizations/ @imatwawana
|
||||
@@ -66,9 +66,13 @@
|
||||
/scripts/go-workspace @grafana/grafana-app-platform-squad
|
||||
/hack/ @grafana/grafana-app-platform-squad
|
||||
|
||||
/apps/alerting/ @grafana/alerting-backend @grafana/alerting-frontend
|
||||
/pkg/apis/provisioning @grafana/grafana-git-ui-sync-team
|
||||
/pkg/registry/apis/provisioning @grafana/grafana-git-ui-sync-team
|
||||
|
||||
/apps/alerting/ @grafana/alerting-backend
|
||||
/apps/playlist/ @grafana/grafana-app-platform-squad
|
||||
/apps/investigation/ @fcjack @matryer
|
||||
/apps/investigations/ @fcjack @matryer @svennergr
|
||||
/apps/advisor/ @grafana/plugins-platform-backend
|
||||
/pkg/api/ @grafana/grafana-backend-group
|
||||
/pkg/apis/ @grafana/grafana-app-platform-squad
|
||||
/pkg/apis/query @grafana/grafana-datasources-core-services
|
||||
@@ -237,6 +241,7 @@
|
||||
/devenv/dev-dashboards/extensions/ @grafana/plugins-platform-frontend
|
||||
|
||||
/devenv/docker/blocks/alert_webhook_listener/ @grafana/alerting-backend
|
||||
/devenv/docker/blocks/stateful_webhook/ @grafana/alerting-backend
|
||||
/devenv/docker/blocks/caddy_tls/ @grafana/alerting-backend
|
||||
/devenv/docker/blocks/clickhouse/ @grafana/partner-datasources
|
||||
/devenv/docker/blocks/collectd/ @grafana/observability-metrics
|
||||
@@ -376,6 +381,11 @@
|
||||
|
||||
/crowdin.yml @grafana/grafana-frontend-platform
|
||||
/public/locales/ @grafana/grafana-frontend-platform
|
||||
/public/locales/de-DE @grafanabot
|
||||
/public/locales/es-ES @grafanabot
|
||||
/public/locales/fr-FR @grafanabot
|
||||
/public/locales/pt-BR @grafanabot
|
||||
/public/locales/zh-Hans @grafanabot
|
||||
/public/app/core/internationalization/ @grafana/grafana-frontend-platform
|
||||
/e2e/ @grafana/grafana-frontend-platform
|
||||
/e2e/cloud-plugins-suite/ @grafana/partner-datasources
|
||||
@@ -401,7 +411,7 @@
|
||||
/packages/grafana-schema/src/**/*canvas* @grafana/dataviz-squad
|
||||
/packages/grafana-schema/src/**/*tempo* @grafana/observability-traces-and-profiling
|
||||
/packages/grafana-sql/ @grafana/partner-datasources @grafana/oss-big-tent
|
||||
/packages/grafana-ui/.storybook/ @grafana/plugins-platform-frontend
|
||||
/packages/grafana-ui/.storybook/ @grafana/grafana-frontend-platform
|
||||
/packages/grafana-ui/src/components/ @grafana/grafana-frontend-platform
|
||||
/packages/grafana-ui/src/components/BarGauge/ @grafana/dataviz-squad
|
||||
/packages/grafana-ui/src/components/DataLinks/ @grafana/dataviz-squad
|
||||
@@ -420,9 +430,7 @@
|
||||
/packages/grafana-ui/src/graveyard/Graph/ @grafana/dataviz-squad
|
||||
/packages/grafana-ui/src/graveyard/GraphNG/ @grafana/dataviz-squad
|
||||
/packages/grafana-ui/src/graveyard/TimeSeries/ @grafana/dataviz-squad
|
||||
/packages/grafana-ui/src/utils/storybook/ @grafana/plugins-platform-frontend
|
||||
|
||||
/plugins-bundled/ @grafana/plugins-platform-frontend
|
||||
/packages/grafana-ui/src/utils/storybook/ @grafana/grafana-frontend-platform
|
||||
|
||||
# root files, mostly frontend
|
||||
/.browserslistrc @grafana/frontend-ops
|
||||
@@ -436,6 +444,7 @@
|
||||
/.betterer.eslint.config.js @grafana/frontend-ops
|
||||
/.gitattributes @grafana/frontend-ops
|
||||
/.gitignore @grafana/frontend-ops
|
||||
/.ignore @grafana/frontend-ops
|
||||
/.nvmrc @grafana/frontend-ops
|
||||
/.prettierignore @grafana/frontend-ops
|
||||
/.yarn @grafana/frontend-ops
|
||||
@@ -456,6 +465,7 @@
|
||||
playwright.config.ts @grafana/plugins-platform-frontend
|
||||
|
||||
# public folder
|
||||
/public/app/api/ @grafana/grafana-frontend-platform
|
||||
/public/app/core/ @grafana/grafana-frontend-platform
|
||||
/public/app/core/components/TimePicker/ @grafana/grafana-frontend-platform
|
||||
/public/app/core/components/Layers/ @grafana/dataviz-squad
|
||||
@@ -492,6 +502,7 @@ playwright.config.ts @grafana/plugins-platform-frontend
|
||||
/public/app/features/explore/ @grafana/observability-traces-and-profiling
|
||||
/public/app/features/expressions/ @grafana/observability-metrics
|
||||
/public/app/features/folders/ @grafana/grafana-frontend-platform
|
||||
/public/app/features/iam/ @grafana/grafana-frontend-platform
|
||||
/public/app/features/inspector/ @grafana/dashboards-squad
|
||||
/public/app/features/invites/ @grafana/grafana-frontend-platform
|
||||
/public/app/features/library-panels/ @grafana/dashboards-squad
|
||||
@@ -505,7 +516,6 @@ playwright.config.ts @grafana/plugins-platform-frontend
|
||||
/public/app/features/playlist/ @grafana/dashboards-squad
|
||||
/public/app/features/plugins/ @grafana/plugins-platform-frontend
|
||||
/public/app/features/profile/ @grafana/grafana-frontend-platform
|
||||
/public/app/features/query-library/ @grafana/grafana-frontend-platform
|
||||
/public/app/features/runtime/ @ryantxu
|
||||
/public/app/features/query/ @grafana/dashboards-squad
|
||||
/public/app/features/sandbox/ @grafana/grafana-frontend-platform
|
||||
@@ -534,6 +544,7 @@ playwright.config.ts @grafana/plugins-platform-frontend
|
||||
/public/app/plugins/panel/heatmap/ @grafana/dataviz-squad
|
||||
/public/app/plugins/panel/histogram/ @grafana/dataviz-squad
|
||||
/public/app/plugins/panel/logs/ @grafana/observability-logs
|
||||
/public/app/plugins/panel/logs-new/ @grafana/observability-logs
|
||||
/public/app/plugins/panel/nodeGraph/ @grafana/observability-traces-and-profiling @grafana/app-o11y-visualizations
|
||||
/public/app/plugins/panel/traces/ @grafana/observability-traces-and-profiling
|
||||
/public/app/plugins/panel/flamegraph/ @grafana/observability-traces-and-profiling
|
||||
@@ -582,6 +593,7 @@ playwright.config.ts @grafana/plugins-platform-frontend
|
||||
/public/app/features/explore/NodeGraph/ @grafana/observability-traces-and-profiling
|
||||
/public/app/features/explore/FlameGraph/ @grafana/observability-traces-and-profiling
|
||||
/public/app/features/explore/TraceView/ @grafana/observability-traces-and-profiling
|
||||
/public/app/features/explore/QueryLibrary/ @grafana/grafana-frontend-platform
|
||||
|
||||
/public/api-merged.json @grafana/grafana-backend-group
|
||||
/public/api-enterprise-spec.json @grafana/grafana-backend-group
|
||||
@@ -594,9 +606,6 @@ playwright.config.ts @grafana/plugins-platform-frontend
|
||||
/public/app/AppWrapper.tsx @grafana/frontend-ops
|
||||
/public/app/partials/ @grafana/grafana-frontend-platform
|
||||
|
||||
|
||||
|
||||
|
||||
/scripts/benchmark-access-control.sh @grafana/access-squad
|
||||
/scripts/check-breaking-changes.sh @grafana/plugins-platform-frontend
|
||||
/scripts/ci-* @grafana/grafana-developer-enablement-squad
|
||||
@@ -621,6 +630,7 @@ playwright.config.ts @grafana/plugins-platform-frontend
|
||||
/scripts/cleanup-husky.sh @grafana/frontend-ops
|
||||
/scripts/verify-repo-update/ @grafana/grafana-developer-enablement-squad
|
||||
/scripts/generate-rtk-apis.ts @grafana/grafana-frontend-platform
|
||||
/scripts/process-specs.ts @grafana/grafana-frontend-platform
|
||||
/scripts/generate-alerting-rtk-apis.ts @grafana/alerting-frontend
|
||||
/scripts/levitate-parse-json-report.js @grafana/plugins-platform-frontend
|
||||
/scripts/levitate-show-affected-plugins.js @grafana/plugins-platform-frontend
|
||||
@@ -634,9 +644,6 @@ playwright.config.ts @grafana/plugins-platform-frontend
|
||||
.betterer.results @grafanabot
|
||||
.betterer.ts @grafana/grafana-frontend-platform
|
||||
|
||||
# @grafana/ui component documentation
|
||||
*.mdx @grafana/plugins-platform-frontend
|
||||
|
||||
# Design system
|
||||
/public/img/icons/unicons/ @grafana/design-system
|
||||
|
||||
@@ -727,6 +734,7 @@ embed.go @grafana/grafana-as-code
|
||||
/pkg/registry/apis/alerting @grafana/grafana-app-platform-squad @grafana/alerting-backend
|
||||
/pkg/registry/apis/query @grafana/grafana-datasources-core-services
|
||||
/pkg/registry/apis/userstorage @grafana/grafana-app-platform-squad @grafana/plugins-platform-backend
|
||||
/pkg/registry/apps/advisor @grafana/plugins-platform-backend
|
||||
/pkg/codegen/ @grafana/grafana-as-code
|
||||
/pkg/codegen/generators @grafana/grafana-as-code
|
||||
/pkg/kinds/*/*_gen.go @grafana/grafana-as-code
|
||||
@@ -746,6 +754,7 @@ embed.go @grafana/grafana-as-code
|
||||
/.github/pr-checks.json @tolzhabayev
|
||||
/.github/pr-commands.json @tolzhabayev
|
||||
/.github/renovate.json5 @grafana/frontend-ops
|
||||
/.github/workflows/add-to-whats-new.yml @grafana/docs-tooling
|
||||
/.github/workflows/auto-triager/ @grafana/plugins-platform-frontend
|
||||
/.github/workflows/alerting-swagger-gen.yml @grafana/alerting-backend
|
||||
/.github/workflows/auto-milestone.yml @grafana/grafana-developer-enablement-squad
|
||||
@@ -754,11 +763,14 @@ embed.go @grafana/grafana-as-code
|
||||
/.github/workflows/close-milestone.yml @grafana/grafana-developer-enablement-squad
|
||||
/.github/workflows/release-pr.yml @grafana/grafana-developer-enablement-squad
|
||||
/.github/workflows/release-comms.yml @grafana/grafana-developer-enablement-squad
|
||||
/.github/workflows/migrate-prs.yml @grafana/grafana-developer-enablement-squad
|
||||
/.github/workflows/create-next-release-branch.yml @grafana/grafana-developer-enablement-squad
|
||||
/.github/workflows/codeowners-validator.yml @tolzhabayev
|
||||
/.github/workflows/codeql-analysis.yml @DanCech
|
||||
/.github/workflows/commands.yml @torkelo
|
||||
/.github/workflows/community-release.yml @grafana/grafana-developer-enablement-squad
|
||||
/.github/workflows/detect-breaking-changes-* @grafana/plugins-platform-frontend
|
||||
/.github/workflows/documentation-ci.yml @grafana/docs-tooling
|
||||
/.github/workflows/doc-validator.yml @grafana/docs-tooling
|
||||
/.github/workflows/deploy-pr-preview.yml @grafana/docs-tooling
|
||||
/.github/workflows/epic-add-to-platform-ux-parent-project.yml @meanmina
|
||||
@@ -776,16 +788,16 @@ embed.go @grafana/grafana-as-code
|
||||
/.github/workflows/publish-technical-documentation-next.yml @grafana/docs-tooling
|
||||
/.github/workflows/publish-technical-documentation-release.yml @grafana/docs-tooling
|
||||
/.github/workflows/remove-milestone.yml @grafana/grafana-developer-enablement-squad
|
||||
/.github/workflows/sbom-report.yml @grafana/security-team
|
||||
/.github/workflows/scripts/json-file-to-job-output.js @grafana/plugins-platform-frontend
|
||||
/.github/workflows/stale.yml @grafana/grafana-developer-enablement-squad
|
||||
/.github/workflows/update-changelog.yml @grafana/grafana-developer-enablement-squad
|
||||
/.github/workflows/update-make-docs.yml @grafana/docs-tooling
|
||||
/.github/workflows/scripts/kinds/verify-kinds.go @grafana/platform-cat
|
||||
/.github/workflows/publish-kinds-next.yml @grafana/platform-cat
|
||||
/.github/workflows/publish-kinds-release.yml @grafana/platform-cat
|
||||
/.github/workflows/verify-kinds.yml @grafana/platform-cat
|
||||
/.github/workflows/scripts/kinds/verify-kinds.go @grafana/platform-monitoring
|
||||
/.github/workflows/publish-kinds-next.yml @grafana/platform-monitoring
|
||||
/.github/workflows/publish-kinds-release.yml @grafana/platform-monitoring
|
||||
/.github/workflows/verify-kinds.yml @grafana/platform-monitoring
|
||||
/.github/workflows/dashboards-issue-add-label.yml @grafana/dashboards-squad
|
||||
/.github/workflows/run-schema-v2-e2e.yml @grafana/dashboards-squad
|
||||
/.github/workflows/ephemeral-instances-pr-comment.yml @grafana/grafana-backend-services-squad
|
||||
/.github/workflows/create-security-patch-from-security-mirror.yml @grafana/grafana-developer-enablement-squad
|
||||
/.github/workflows/core-plugins-build-and-release.yml @grafana/plugins-platform-frontend @grafana/plugins-platform-backend
|
||||
|
||||
2
.github/dependabot.yml
vendored
2
.github/dependabot.yml
vendored
@@ -8,7 +8,7 @@ updates:
|
||||
directories:
|
||||
- "/"
|
||||
- "/apps/playlist"
|
||||
- "/apps/investigation"
|
||||
- "/apps/investigations"
|
||||
- "/pkg/aggregator"
|
||||
- "/pkg/apimachinery"
|
||||
- "/pkg/apiserver"
|
||||
|
||||
6
.github/pr-commands.json
vendored
6
.github/pr-commands.json
vendored
@@ -14,7 +14,6 @@
|
||||
"public/**/*",
|
||||
"packages/**/*",
|
||||
"e2e/**/*",
|
||||
"plugins-bundled/**/*",
|
||||
"scripts/build/release-packages.sh",
|
||||
"scripts/circle-release-next-packages.sh",
|
||||
"scripts/ci-frontend-metrics.sh",
|
||||
@@ -248,7 +247,8 @@
|
||||
"/pkg/services/sqlstore/migrations/ualert/**/*",
|
||||
"/pkg/services/alerting/**/*",
|
||||
"/public/app/features/alerting/**/*",
|
||||
"/pkg/tests/api/alerting/**/*"
|
||||
"/pkg/tests/api/alerting/**/*",
|
||||
"/pkg/tests/alertmanager/**/*"
|
||||
],
|
||||
"action": "updateLabel",
|
||||
"addLabel": "area/alerting"
|
||||
@@ -437,4 +437,4 @@
|
||||
"action": "updateLabel",
|
||||
"addLabel": "area/panel/table"
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
3
.github/renovate.json5
vendored
3
.github/renovate.json5
vendored
@@ -13,13 +13,12 @@
|
||||
"slate-react", // we don't want to continue using this on the long run, use Monaco editor instead of Slate
|
||||
"@types/slate-react", // we don't want to continue using this on the long run, use Monaco editor instead of Slate
|
||||
"@types/slate", // we don't want to continue using this on the long run, use Monaco editor instead of Slate
|
||||
"storybook-dark-mode", // 4.0.2 causes storybook 8.4 to break with react hooks errors
|
||||
// Temporarily pause updating lerna and nx until we resolve build issues
|
||||
"lerna",
|
||||
"nx"
|
||||
],
|
||||
includePaths: ["package.json", "packages/**", "public/app/plugins/**"],
|
||||
ignorePaths: ["emails/**", "plugins-bundled/**", "**/mocks/**"],
|
||||
ignorePaths: ["emails/**", "**/mocks/**"],
|
||||
labels: ["area/frontend", "dependencies", "no-changelog"],
|
||||
postUpdateOptions: ["yarnDedupeHighest"],
|
||||
packageRules: [
|
||||
|
||||
46
.github/workflows/actions/changelog/index.js
vendored
46
.github/workflows/actions/changelog/index.js
vendored
@@ -69,8 +69,17 @@ const graphql = async (ghtoken, query, variables) => {
|
||||
},
|
||||
body: JSON.stringify({ query, variables }),
|
||||
});
|
||||
const { data } = await results.json();
|
||||
return data;
|
||||
|
||||
const res = await results.json();
|
||||
|
||||
LOG(
|
||||
JSON.stringify({
|
||||
status: results.status,
|
||||
text: results.statusText,
|
||||
})
|
||||
);
|
||||
|
||||
return res.data;
|
||||
};
|
||||
|
||||
// Using Github GraphQL API find the timestamp for the given tag/commit hash.
|
||||
@@ -99,20 +108,20 @@ const getCommitishDate = async (name, owner, target) => {
|
||||
// Using Github GraphQL API get a list of PRs between the two "commitish" items.
|
||||
// This resoves the "since" item's timestamp first and iterates over all PRs
|
||||
// till "target" using naïve pagination.
|
||||
const getHistory = async (name, owner, target, sinceDate) => {
|
||||
LOG(`Fetching ${owner}/${name} PRs since ${sinceDate} till ${target}`);
|
||||
const getHistory = async (name, owner, from, to) => {
|
||||
LOG(`Fetching ${owner}/${name} PRs between ${from} and ${to}`);
|
||||
const query = `
|
||||
query findCommitsWithAssociatedPullRequests(
|
||||
$name: String!
|
||||
$owner: String!
|
||||
$target: String!
|
||||
$sinceDate: GitTimestamp
|
||||
$from: String!
|
||||
$to: String!
|
||||
$cursor: String
|
||||
) {
|
||||
repository(name: $name, owner: $owner) {
|
||||
object(expression: $target) {
|
||||
... on Commit {
|
||||
history(first: 50, since: $sinceDate, after: $cursor) {
|
||||
ref(qualifiedName: $from) {
|
||||
compare(headRef: $to) {
|
||||
commits(first: 25, after: $cursor) {
|
||||
totalCount
|
||||
pageInfo {
|
||||
hasNextPage
|
||||
@@ -155,13 +164,13 @@ const getHistory = async (name, owner, target, sinceDate) => {
|
||||
const result = await graphql(ghtoken, query, {
|
||||
name,
|
||||
owner,
|
||||
target,
|
||||
sinceDate,
|
||||
from,
|
||||
to,
|
||||
cursor,
|
||||
});
|
||||
LOG(`GraphQL: ${JSON.stringify(result)}`);
|
||||
nodes = [...nodes, ...result.repository.object.history.nodes];
|
||||
const { hasNextPage, endCursor } = result.repository.object.history.pageInfo;
|
||||
nodes = [...nodes, ...result.repository.ref.compare.commits.nodes];
|
||||
const { hasNextPage, endCursor } = result.repository.ref.compare.commits.pageInfo;
|
||||
if (!hasNextPage) {
|
||||
break;
|
||||
}
|
||||
@@ -175,11 +184,11 @@ const getHistory = async (name, owner, target, sinceDate) => {
|
||||
// feature, deprecation, breaking change and plugin fixes/enhancements).
|
||||
//
|
||||
// PR grouping relies on Github labels only, not on the PR contents.
|
||||
const getChangeLogItems = async (name, owner, sinceDate, to) => {
|
||||
const getChangeLogItems = async (name, owner, from, to) => {
|
||||
// check if a node contains a certain label
|
||||
const hasLabel = ({ labels }, label) => labels.nodes.some(({ name }) => name === label);
|
||||
// get all the PRs between the two "commitish" items
|
||||
const history = await getHistory(name, owner, to, sinceDate);
|
||||
const history = await getHistory(name, owner, from, to);
|
||||
|
||||
const items = history.flatMap((node) => {
|
||||
// discard PRs without a "changelog" label
|
||||
@@ -231,13 +240,10 @@ const previous = process.argv[3] || process.env.INPUT_PREVIOUS || (await getPrev
|
||||
|
||||
LOG(`Previous tag/commit: ${previous}`);
|
||||
|
||||
const sinceDate = await getCommitishDate('grafana', 'grafana', previous);
|
||||
LOG(`Previous tag/commit timestamp: ${sinceDate}`);
|
||||
|
||||
// Get all changelog items from Grafana OSS
|
||||
const oss = await getChangeLogItems('grafana', 'grafana', sinceDate, target);
|
||||
const oss = await getChangeLogItems('grafana', 'grafana', previous, target);
|
||||
// Get all changelog items from Grafana Enterprise
|
||||
const entr = await getChangeLogItems('grafana-enterprise', 'grafana', sinceDate, target);
|
||||
const entr = await getChangeLogItems('grafana-enterprise', 'grafana', previous, target);
|
||||
|
||||
LOG(`Found OSS PRs: ${oss.length}`);
|
||||
LOG(`Found Enterprise PRs: ${entr.length}`);
|
||||
|
||||
16
.github/workflows/add-to-whats-new.yml
vendored
Normal file
16
.github/workflows/add-to-whats-new.yml
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
name: Add comment about adding a What's new note
|
||||
on:
|
||||
pull_request:
|
||||
types: [labeled]
|
||||
|
||||
jobs:
|
||||
add-comment:
|
||||
if: ${{ ! github.event.pull_request.head.repo.fork && contains(github.event.pull_request.labels.*.name, 'add to what''s new') }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: marocchino/sticky-pull-request-comment@52423e01640425a022ef5fd42c6fb5f633a02728 # v2.9.1
|
||||
with:
|
||||
message: |
|
||||
Since you've added the `Add to what's new` label, consider drafting a [What's new note](https://admin.grafana.com/content-admin/#/collections/whats-new/new) for this feature.
|
||||
16
.github/workflows/backport.yml
vendored
16
.github/workflows/backport.yml
vendored
@@ -10,24 +10,18 @@ jobs:
|
||||
if: github.repository == 'grafana/grafana'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Actions
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: "grafana/grafana-github-actions"
|
||||
path: ./actions
|
||||
ref: main
|
||||
- name: Install Actions
|
||||
run: npm install --production --prefix ./actions
|
||||
- name: "Generate token"
|
||||
id: generate_token
|
||||
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92
|
||||
with:
|
||||
app_id: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }}
|
||||
private_key: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }}
|
||||
- run: git config --global user.email '132647405+grafana-delivery-bot[bot]@users.noreply.github.com'
|
||||
- run: git config --global user.name 'grafana-delivery-bot[bot]'
|
||||
- run: git remote set-url origin "https://grafana-delivery-bot:${{ steps.generate_token.outputs.token }}@github.com/grafana/grafana.git"
|
||||
- name: Run backport
|
||||
uses: ./actions/backport
|
||||
uses: grafana/grafana-github-actions-go/backport@main
|
||||
with:
|
||||
metricsWriteAPIKey: ${{secrets.GRAFANA_MISC_STATS_API_KEY}}
|
||||
token: ${{ steps.generate_token.outputs.token }}
|
||||
labelsToAdd: "backport"
|
||||
title: "[{{base}}] {{originalTitle}}"
|
||||
|
||||
43
.github/workflows/create-next-release-branch.yml
vendored
Normal file
43
.github/workflows/create-next-release-branch.yml
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
name: Create next release branch
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
ownerRepo:
|
||||
type: string
|
||||
description: Owner/repo of the repository where the branch is created (e.g. 'grafana/grafana')
|
||||
required: true
|
||||
source:
|
||||
description: The release branch to increment (eg providing `release-11.2.3` will result in `release-11.2.4` being created)
|
||||
type: string
|
||||
required: true
|
||||
secrets:
|
||||
token:
|
||||
required: true
|
||||
outputs:
|
||||
branch:
|
||||
description: The new branch that was created
|
||||
value: ${{ jobs.main.outputs.branch }}
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
ownerRepo:
|
||||
description: Owner/repo of the repository where the branch is created (e.g. 'grafana/grafana')
|
||||
source:
|
||||
description: The release branch to increment (eg providing `release-11.2.3` will result in `release-11.2.4` being created)
|
||||
type: string
|
||||
required: true
|
||||
secrets:
|
||||
token:
|
||||
required: true
|
||||
jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
branch: ${{ steps.branch.outputs.branch }}
|
||||
steps:
|
||||
- name: Create release branch
|
||||
id: branch
|
||||
uses: grafana/grafana-github-actions-go/bump-release@main
|
||||
with:
|
||||
ownerRepo: ${{ inputs.ownerRepo }}
|
||||
source: ${{ inputs.source }}
|
||||
token: ${{ secrets.token }}
|
||||
@@ -11,6 +11,7 @@ on:
|
||||
branches:
|
||||
- "main"
|
||||
- "v*.*.*"
|
||||
- "release-*.*.*"
|
||||
|
||||
# This is run before the pull request has been merged, so we'll run against the src branch
|
||||
jobs:
|
||||
|
||||
19
.github/workflows/documentation-ci.yml
vendored
Normal file
19
.github/workflows/documentation-ci.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
name: Documentation CI
|
||||
on:
|
||||
pull_request:
|
||||
branches: ["main"]
|
||||
paths: ["docs/sources/**"]
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
vale:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: grafana/vale:latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: grafana/writers-toolkit/vale-action@vale-action/v1
|
||||
with:
|
||||
filter: '.Name in ["Grafana.WordList", "Grafana.Spelling", "Grafana.ProductPossessives"]'
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
57
.github/workflows/i18n-crowdin-download.yml
vendored
57
.github/workflows/i18n-crowdin-download.yml
vendored
@@ -3,7 +3,7 @@ name: Crowdin Download Action
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "0 * * * *"
|
||||
- cron: "0 0 * * *"
|
||||
|
||||
jobs:
|
||||
download-sources-from-crowdin:
|
||||
@@ -12,6 +12,7 @@ jobs:
|
||||
permissions:
|
||||
contents: write # needed to commit changes into the PR
|
||||
pull-requests: write # needed to update PR description, labels, etc
|
||||
id-token: write # needed to get vault secrets
|
||||
|
||||
steps:
|
||||
- name: Generate token
|
||||
@@ -41,17 +42,11 @@ jobs:
|
||||
pull_request_body: |
|
||||
:robot: Automatic download of translations from Crowdin.
|
||||
|
||||
Steps for merging:
|
||||
1. A quick sanity check of the changes and approve. Things to look out for:
|
||||
- No changes in the English file. The source of truth is in the main branch, NOT in Crowdin.
|
||||
- Translations maybe be removed if the English phrase was removed, but there should not be many of these
|
||||
- Anything else that looks 'funky'. Ask if you're not sure.
|
||||
2. Approve & (Auto-)merge. :tada:
|
||||
This runs once per day and will merge automatically if all the required checks pass.
|
||||
|
||||
If there's a conflict, close the pull request and **delete the branch**. A GH action will recreate the pull request.
|
||||
Remember, the longer this pull request is open, the more likely it is that it'll get conflicts.
|
||||
If there's a conflict, close the pull request and **delete the branch**.
|
||||
You can then either wait for the schedule to trigger a new PR, or rerun the action manually.
|
||||
pull_request_labels: 'area/frontend, area/internationalization, no-changelog, no-backport'
|
||||
pull_request_reviewers: 'grafana-frontend-platform'
|
||||
pull_request_base_branch_name: 'main'
|
||||
base_url: 'https://grafana.api.crowdin.com'
|
||||
config: 'crowdin.yml'
|
||||
@@ -119,3 +114,45 @@ jobs:
|
||||
with:
|
||||
pr: ${{ steps.crowdin-download.outputs.pull_request_number }}
|
||||
token: ${{ steps.generate_token.outputs.token }}
|
||||
|
||||
- name: Get vault secrets
|
||||
id: vault-secrets
|
||||
uses: grafana/shared-workflows/actions/get-vault-secrets@main
|
||||
with:
|
||||
# Secrets placed in ci/repo/grafana/grafana/grafana-pr-approver
|
||||
repo_secrets: |
|
||||
GRAFANA_PR_APPROVER_APP_ID=grafana-pr-approver:app-id
|
||||
GRAFANA_PR_APPROVER_APP_PEM=grafana-pr-approver:private-key
|
||||
|
||||
- name: Generate approver token
|
||||
if: steps.crowdin-download.outputs.pull_request_url
|
||||
id: generate_approver_token
|
||||
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92
|
||||
with:
|
||||
app_id: ${{ env.GRAFANA_PR_APPROVER_APP_ID }}
|
||||
private_key: ${{ env.GRAFANA_PR_APPROVER_APP_PEM }}
|
||||
|
||||
- name: Approve and automerge PR
|
||||
if: steps.crowdin-download.outputs.pull_request_url
|
||||
shell: bash
|
||||
# Only approve if:
|
||||
# - the PR does not modify files other than json files under the public/locales/ directory
|
||||
# - the PR does not modify the en-US locale
|
||||
run: |
|
||||
filesChanged=$(gh pr diff --name-only ${{ steps.crowdin-download.outputs.pull_request_url }})
|
||||
|
||||
if [[ $(echo $filesChanged | grep -v 'public/locales/[a-zA-Z\-]*/grafana.json' | wc -l) -ne 0 ]]; then
|
||||
echo "Non-i18n changes detected, not approving"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $(echo $filesChanged | grep "public/locales/en-US" | wc -l) -ne 0 ]]; then
|
||||
echo "public/locales/en-US changes detected, not approving"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Approving and enabling automerge"
|
||||
gh pr review ${{ steps.crowdin-download.outputs.pull_request_url }} --approve
|
||||
gh pr merge --auto --squash ${{ steps.crowdin-download.outputs.pull_request_url }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.generate_approver_token.outputs.token }}
|
||||
|
||||
50
.github/workflows/migrate-prs.yml
vendored
Normal file
50
.github/workflows/migrate-prs.yml
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
name: Migrate open PRs
|
||||
# Migrate open PRs from a superseded release branch to the current release branch and notify authors
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
from:
|
||||
description: 'The base branch to check for open PRs'
|
||||
required: true
|
||||
type: string
|
||||
to:
|
||||
description: 'The base branch to migrate open PRs to'
|
||||
required: true
|
||||
type: string
|
||||
ownerRepo:
|
||||
description: Owner/repo of the repository where the branch is created (e.g. 'grafana/grafana')
|
||||
required: true
|
||||
type: string
|
||||
secrets:
|
||||
token:
|
||||
required: true
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
from:
|
||||
description: 'The base branch to check for open PRs'
|
||||
required: true
|
||||
type: string
|
||||
to:
|
||||
description: 'The base branch to migrate open PRs to'
|
||||
required: true
|
||||
type: string
|
||||
ownerRepo:
|
||||
description: Owner/repo of the repository where the branch is created (e.g. 'grafana/grafana')
|
||||
required: true
|
||||
type: string
|
||||
secrets:
|
||||
token:
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Migrate PRs
|
||||
uses: grafana/grafana-github-actions-go/migrate-open-prs@main
|
||||
with:
|
||||
token: ${{ secrets.token }}
|
||||
ownerRepo: ${{ inputs.ownerRepo }}
|
||||
from: ${{ inputs.from }}
|
||||
to: ${{ inputs.to }}
|
||||
binary_release_tag: 'dev'
|
||||
@@ -3,7 +3,7 @@ name: publish-technical-documentation-release
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- v[0-9]+.[0-9]+.x
|
||||
- release-[0-9]+.[0-9]+.[0-9]+
|
||||
tags:
|
||||
- v[0-9]+.[0-9]+.[0-9]+
|
||||
paths:
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
- uses: grafana/writers-toolkit/publish-technical-documentation-release@publish-technical-documentation-release/v2
|
||||
with:
|
||||
release_tag_regexp: "^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$"
|
||||
release_branch_regexp: "^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.x$"
|
||||
release_branch_with_patch_regexp: "^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$"
|
||||
release_branch_regexp: "^release-(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$"
|
||||
release_branch_with_patch_regexp: "^release-(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$"
|
||||
website_directory: content/docs/grafana
|
||||
version_suffix: ""
|
||||
|
||||
50
.github/workflows/release-comms.yml
vendored
50
.github/workflows/release-comms.yml
vendored
@@ -27,10 +27,18 @@ jobs:
|
||||
name: Setup and establish latest
|
||||
outputs:
|
||||
version: ${{ steps.output.outputs.version }}
|
||||
release_branch: ${{ steps.output.outputs.release_branch }}
|
||||
dry_run: ${{ steps.output.outputs.dry_run }}
|
||||
latest: ${{ steps.output.outputs.latest }}
|
||||
token: ${{ steps.output.outputs.token }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: "Generate token"
|
||||
id: generate_token
|
||||
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92
|
||||
with:
|
||||
app_id: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }}
|
||||
private_key: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }}
|
||||
# The github-release action expects a `LATEST` value of a string of either '1' or '0'
|
||||
- if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
run: |
|
||||
@@ -49,9 +57,51 @@ jobs:
|
||||
echo "latest: $LATEST"
|
||||
echo "version: $VERSION"
|
||||
|
||||
echo "release_branch=$(echo $VERSION | sed -s 's/^v/release-/g')" >> "$GITHUB_OUTPUT"
|
||||
echo "token=${{ steps.generate_token.outputs.token }}" >> "$GITHUB_OUTPUT"
|
||||
echo "dry_run=$DRY_RUN" >> "$GITHUB_OUTPUT"
|
||||
echo "latest=$LATEST" >> "$GITHUB_OUTPUT"
|
||||
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
||||
create_next_release_branch_grafana:
|
||||
name: Create next release branch (Grafana)
|
||||
needs: setup
|
||||
uses: ./.github/workflows/create-next-release-branch.yml
|
||||
with:
|
||||
ownerRepo: 'grafana/grafana'
|
||||
source: ${{ needs.setup.outputs.release_branch }}
|
||||
secrets:
|
||||
token: ${{ needs.setup.outputs.token }}
|
||||
create_next_release_branch_enterprise:
|
||||
name: Create next release branch (Grafana Enterprise)
|
||||
needs: setup
|
||||
uses: ./.github/workflows/create-next-release-branch.yml
|
||||
with:
|
||||
ownerRepo: 'grafana/grafana'
|
||||
source: ${{ needs.setup.outputs.release_branch }}
|
||||
secrets:
|
||||
token: ${{ needs.setup.outputs.token }}
|
||||
migrate_prs_grafana:
|
||||
needs:
|
||||
- setup
|
||||
- create_next_release_branch_grafana
|
||||
uses: ./.github/workflows/migrate-prs.yml
|
||||
with:
|
||||
ownerRepo: 'grafana/grafana'
|
||||
from: ${{ needs.setup.outputs.release_branch }}
|
||||
to: ${{ needs.create_next_release_branch_grafana.outputs.branch }}
|
||||
secrets:
|
||||
token: ${{ needs.setup.outputs.token }}
|
||||
migrate_prs_enterprise:
|
||||
needs:
|
||||
- setup
|
||||
- create_next_release_branch_enterprise
|
||||
uses: ./.github/workflows/migrate-prs.yml
|
||||
with:
|
||||
ownerRepo: 'grafana/grafana-enterprise'
|
||||
from: ${{ needs.setup.outputs.release_branch }}
|
||||
to: ${{ needs.create_next_release_branch_enterprise.outputs.branch }}
|
||||
secrets:
|
||||
token: ${{ needs.setup.outputs.token }}
|
||||
post_changelog_on_forum:
|
||||
needs: setup
|
||||
uses: ./.github/workflows/community-release.yml
|
||||
|
||||
20
.github/workflows/release-pr.yml
vendored
20
.github/workflows/release-pr.yml
vendored
@@ -4,7 +4,7 @@
|
||||
# Please refrain from including any processes that do not result in code changes in this workflow. Instead, they should
|
||||
# either be triggered in the release promotion process or in the release comms process (that is triggered by merging
|
||||
# this PR).
|
||||
name: Complete a Grafana release
|
||||
name: Grafana Release PR
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
@@ -19,7 +19,7 @@ on:
|
||||
target:
|
||||
required: true
|
||||
type: string
|
||||
description: The base branch that these changes are being merged into
|
||||
description: The release branch pattern (eg v9.5.x) that these changes are being merged into
|
||||
backport:
|
||||
required: false
|
||||
type: string
|
||||
@@ -61,10 +61,17 @@ jobs:
|
||||
with:
|
||||
app_id: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }}
|
||||
private_key: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }}
|
||||
- name: Get release branch
|
||||
id: branch
|
||||
uses: grafana/grafana-github-actions-go/latest-release-branch@main
|
||||
with:
|
||||
token: ${{ steps.generate_token.outputs.token }}
|
||||
ownerRepo: 'grafana/grafana'
|
||||
pattern: ${{ inputs.target }}
|
||||
- name: Checkout Grafana
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.target }}
|
||||
ref: ${{ steps.branch.outputs.branch }}
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
- name: Checkout Grafana (main)
|
||||
@@ -124,7 +131,6 @@ jobs:
|
||||
rm -f CHANGELOG.part changelog_items.md
|
||||
|
||||
git diff CHANGELOG.md
|
||||
|
||||
- name: "Prettify CHANGELOG.md"
|
||||
run: npx prettier --write CHANGELOG.md
|
||||
- name: Commit CHANGELOG.md changes
|
||||
@@ -137,7 +143,7 @@ jobs:
|
||||
|
||||
- name: Add package.json changes
|
||||
run: |
|
||||
git add package.json lerna.json yarn.lock packages public
|
||||
git add package.json lerna.json yarn.lock packages public e2e/test-plugins
|
||||
git commit -m "Update version to ${{ inputs.version }}"
|
||||
|
||||
- name: Git push
|
||||
@@ -151,7 +157,7 @@ jobs:
|
||||
$( [ "x${{ inputs.latest }}" == "xtrue" ] && printf %s '-l "release/latest"') \
|
||||
-l "no-changelog" \
|
||||
--dry-run=${{ inputs.dry_run }} \
|
||||
-B "${{ inputs.target }}" \
|
||||
-B "${{ steps.branch.outputs.branch }}" \
|
||||
--title "Release: ${{ inputs.version }}" \
|
||||
--body "These code changes must be merged after a release is complete"
|
||||
env:
|
||||
@@ -165,7 +171,7 @@ jobs:
|
||||
-l "product-approved" \
|
||||
-l "no-changelog" \
|
||||
--dry-run=${{ inputs.dry_run }} \
|
||||
-B "${{ inputs.target }}" \
|
||||
-B "${{ steps.branch.outputs.branch }}" \
|
||||
--title "Release: ${{ inputs.version }}" \
|
||||
--body "These code changes must be merged after a release is complete"
|
||||
env:
|
||||
|
||||
44
.github/workflows/run-schema-v2-e2e.yml
vendored
Normal file
44
.github/workflows/run-schema-v2-e2e.yml
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
name: Run dashboard schema v2 e2e
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
branches:
|
||||
- '**'
|
||||
|
||||
env:
|
||||
ARCH: linux-amd64
|
||||
|
||||
jobs:
|
||||
dashboard-schema-v2-e2e:
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: true
|
||||
if: github.event.pull_request.draft == false
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Pin Go version to mod file
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: 'go.mod'
|
||||
- run: go version
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
cache: 'yarn'
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable
|
||||
- name: Build grafana
|
||||
run: make build
|
||||
- name: Install Cypress dependencies
|
||||
uses: cypress-io/github-action@v6
|
||||
with:
|
||||
runTests: false
|
||||
- name: Run dashboard scenes e2e
|
||||
run: yarn e2e:schema-v2 || echo "Test failed but marking as success since schema V2 is behind a feature flag and should not block PRs"
|
||||
|
||||
- name: Always succeed # This is a workaround to make the job pass even if the previous step fails
|
||||
if: failure()
|
||||
run: exit 0
|
||||
15
.github/workflows/sbom-report.yml
vendored
15
.github/workflows/sbom-report.yml
vendored
@@ -1,15 +0,0 @@
|
||||
name: syft-sbom-ci
|
||||
on:
|
||||
release:
|
||||
types: [ published ]
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
syft-sbom:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Anchore SBOM Action
|
||||
uses: grafana/shared-workflows/actions@syft-sbom-v0.0.1
|
||||
with:
|
||||
artifact-name: ${{ github.event.repository.name }}-spdx.json
|
||||
13
.github/workflows/trivy-scan.yml
vendored
13
.github/workflows/trivy-scan.yml
vendored
@@ -27,11 +27,14 @@ jobs:
|
||||
trivy fs --no-progress --download-db-only --db-repository public.ecr.aws/aquasecurity/trivy-db
|
||||
- name: Run Trivy vulnerability scanner (table output)
|
||||
# Use the trivy binary rather than the aquasecurity/trivy-action action
|
||||
# to avoid a few bugs
|
||||
# scan the filesystem, rather than building a Docker image prior - the
|
||||
# downside is we won't catch dependencies that are only installed in the
|
||||
# image, but the upside is we'll only catch vulnerabilities that are
|
||||
# explicitly in the our dependencies
|
||||
# to avoid a few bugs.
|
||||
#
|
||||
# We scan the file system rather than building the Docker image to only scan
|
||||
# our direct dependencies. The Docker images are still scanned by
|
||||
# Vulnerability Observability:
|
||||
# - OSS: https://ops.grafana-ops.net/a/grafana-vulnerabilityobs-app/projects/sources/1
|
||||
# - Enterprise: https://ops.grafana-ops.net/a/grafana-vulnerabilityobs-app/projects/sources/12
|
||||
# (If these links are outdated, just go to the list and find the images manually.)
|
||||
run: |
|
||||
trivy fs \
|
||||
--scanners vuln \
|
||||
|
||||
17
.gitignore
vendored
17
.gitignore
vendored
@@ -40,6 +40,7 @@ __debug_bin*
|
||||
# This is the new place of the block, but I leave the previous here for a while
|
||||
/devenv/docker/blocks/auth/saml-enterprise
|
||||
/devenv/docker/blocks/auth/signer
|
||||
/devenv/docker/blocks/spanner_tests
|
||||
|
||||
/tmp
|
||||
tools/phantomjs/phantomjs
|
||||
@@ -103,14 +104,18 @@ profile.cov
|
||||
/pkg/cmd/grafana-cli/grafana-cli
|
||||
/pkg/cmd/grafana-server/grafana-server
|
||||
/pkg/cmd/grafana-server/debug
|
||||
/pkg/extensions/*
|
||||
/pkg/build/cmd/artifactspage.go
|
||||
/pkg/build/cmd/artifactspage.tmpl.html
|
||||
/pkg/build/cmd/exportversion.go
|
||||
/pkg/server/wireexts_enterprise.go
|
||||
|
||||
# Extensions
|
||||
/pkg/cmd/grafana-cli/runner/wireexts_enterprise.go
|
||||
/pkg/server/wireexts_enterprise.go
|
||||
/pkg/build/cmd/enterprise.go
|
||||
/pkg/extensions/*
|
||||
!/pkg/extensions/.keep
|
||||
!/pkg/extensions/main.go
|
||||
/public/app/extensions
|
||||
!/public/app/extensions/.keep
|
||||
|
||||
|
||||
debug.test
|
||||
/examples/*/dist
|
||||
/packaging/**/*.rpm
|
||||
@@ -170,13 +175,13 @@ compilation-stats.json
|
||||
/e2e/benchmarks/**/results
|
||||
/e2e/build_results.zip
|
||||
/e2e/extensions
|
||||
!/e2e/extensions/.keep
|
||||
/e2e/extensions-suite
|
||||
/test-results/
|
||||
/playwright-report/
|
||||
/blob-report/
|
||||
/playwright/.cache/
|
||||
/playwright/.auth/
|
||||
|
||||
# grafana server
|
||||
/scripts/grafana-server/server.log
|
||||
|
||||
|
||||
@@ -191,10 +191,10 @@ linters-settings:
|
||||
allow: []
|
||||
deny:
|
||||
- pkg: github.com/grafana/grafana/pkg
|
||||
desc: apps/investigation is not allowed to import grafana core
|
||||
desc: apps/investigations is not allowed to import grafana core
|
||||
files:
|
||||
- ./apps/investigation/*
|
||||
- ./apps/investigation/**/*
|
||||
- ./apps/investigations/*
|
||||
- ./apps/investigations/**/*
|
||||
gocritic:
|
||||
enabled-checks:
|
||||
- ruleguard
|
||||
|
||||
22
.ignore
Normal file
22
.ignore
Normal file
@@ -0,0 +1,22 @@
|
||||
# This is a trick to ignore files only by git but not by other tools
|
||||
!/public/app/extensions
|
||||
!/pkg/extensions/*
|
||||
!/pkg/cmd/grafana-cli/runner/wireexts_enterprise.go
|
||||
!/pkg/server/wireexts_enterprise.go
|
||||
!/pkg/build/cmd/enterprise.go
|
||||
!/pkg/extensions/*
|
||||
|
||||
# Enterprise emails
|
||||
!/emails/templates/enterprise_*
|
||||
!/public/emails/enterprise_*
|
||||
|
||||
# Enterprise reporting fonts
|
||||
!/public/fonts/dejavu
|
||||
|
||||
# Enterprise devenv
|
||||
!/devenv/docker/blocks/grafana-enterprise
|
||||
!/devenv/docker/blocks/saml-enterprise
|
||||
# This is the new place of the block, but I leave the previous here for a while
|
||||
!/devenv/docker/blocks/auth/saml-enterprise
|
||||
!/devenv/docker/blocks/auth/signer
|
||||
!/devenv/docker/blocks/spanner_tests
|
||||
5
.vale.ini
Normal file
5
.vale.ini
Normal file
@@ -0,0 +1,5 @@
|
||||
MinAlertLevel = warning
|
||||
|
||||
[*]
|
||||
BasedOnStyles = Grafana
|
||||
TokenIgnores = (<http[^\n]+>+?), \*\*[^\n]+\*\*
|
||||
28
.vscode/launch.json
vendored
28
.vscode/launch.json
vendored
@@ -9,12 +9,7 @@
|
||||
"program": "${workspaceFolder}/pkg/cmd/grafana/",
|
||||
"env": {},
|
||||
"cwd": "${workspaceFolder}",
|
||||
"args": [
|
||||
"server",
|
||||
"--homepath", "${workspaceFolder}",
|
||||
"--packaging", "dev",
|
||||
"cfg:app_mode=development",
|
||||
]
|
||||
"args": ["server", "--homepath", "${workspaceFolder}", "--packaging", "dev", "cfg:app_mode=development"]
|
||||
},
|
||||
{
|
||||
"name": "Attach to Test Process",
|
||||
@@ -23,7 +18,7 @@
|
||||
"mode": "remote",
|
||||
"host": "127.0.0.1",
|
||||
"port": 50480,
|
||||
"apiVersion": 2,
|
||||
"apiVersion": 2
|
||||
},
|
||||
{
|
||||
"name": "Run API Server (testdata)",
|
||||
@@ -72,6 +67,16 @@
|
||||
"cwd": "${workspaceFolder}",
|
||||
"args": ["server", "target", "--homepath", "${workspaceFolder}", "--packaging", "dev"]
|
||||
},
|
||||
{
|
||||
"name": "Run Authz server",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "auto",
|
||||
"program": "${workspaceFolder}/pkg/cmd/grafana/",
|
||||
"env": { "GF_DEFAULT_TARGET": "zanzana-server", "GF_SERVER_HTTP_PORT": "3001" },
|
||||
"cwd": "${workspaceFolder}",
|
||||
"args": ["server", "target", "--homepath", "${workspaceFolder}", "--packaging", "dev"]
|
||||
},
|
||||
{
|
||||
"name": "Attach to Chrome",
|
||||
"port": 9222,
|
||||
@@ -91,6 +96,15 @@
|
||||
"NODE_ENV": "test"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Debug ESLint",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "yarn",
|
||||
"runtimeArgs": ["run", "eslint", "${file}"],
|
||||
"console": "integratedTerminal",
|
||||
"internalConsoleOptions": "neverOpen"
|
||||
},
|
||||
{
|
||||
"name": "Debug Go test",
|
||||
"type": "go",
|
||||
|
||||
@@ -13,10 +13,6 @@ packageExtensions:
|
||||
doctrine@3.0.0:
|
||||
dependencies:
|
||||
assert: 2.0.0
|
||||
rc-time-picker@3.7.3:
|
||||
peerDependencies:
|
||||
react: 17.0.1
|
||||
react-dom: 17.0.1
|
||||
rc-trigger@2.6.5:
|
||||
peerDependencies:
|
||||
react: 17.0.1
|
||||
|
||||
293
CHANGELOG.md
293
CHANGELOG.md
@@ -1,3 +1,296 @@
|
||||
<!-- 11.5.1 START -->
|
||||
|
||||
# 11.5.1 (2025-02-03)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- **CodeEditor:** Fix cursor alignment [#99090](https://github.com/grafana/grafana/pull/99090), [@ashharrison90](https://github.com/ashharrison90)
|
||||
- **TransformationFilter**: Include transformation outputs in transformation filtering options: Include transformation outputs in transformation filtering options [#98323](https://github.com/grafana/grafana/pull/98323), [@Sergej-Vlasov](https://github.com/Sergej-Vlasov)
|
||||
|
||||
<!-- 11.5.1 END -->
|
||||
<!-- 11.5.0 START -->
|
||||
|
||||
# 11.5.0 (2025-01-28)
|
||||
|
||||
### Features and enhancements
|
||||
|
||||
- ** CloudMigration:** Create authapi service [#96581](https://github.com/grafana/grafana/pull/96581), [@leandro-deveikis](https://github.com/leandro-deveikis)
|
||||
- **Alerting:** Add new button for exporting new alert rule in HCL format [#96785](https://github.com/grafana/grafana/pull/96785), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
|
||||
- **Alerting:** Add option to show inactive alerts in alert list panel [#96888](https://github.com/grafana/grafana/pull/96888), [@bradleypettit](https://github.com/bradleypettit)
|
||||
- **Alerting:** Add state_periodic_save_batch_size config option [#98019](https://github.com/grafana/grafana/pull/98019), [@alexander-akhmetov](https://github.com/alexander-akhmetov)
|
||||
- **Alerting:** Change default for max_attempts to 3. [#97461](https://github.com/grafana/grafana/pull/97461), [@stevesg](https://github.com/stevesg)
|
||||
- **Alerting:** Consume k8s API for notification policies tree [#96147](https://github.com/grafana/grafana/pull/96147), [@konrad147](https://github.com/konrad147)
|
||||
- **Alerting:** Enable flag alertingApiServer by default [#98282](https://github.com/grafana/grafana/pull/98282), [@yuri-tceretian](https://github.com/yuri-tceretian)
|
||||
- **Alerting:** Explore button in Insights view [#96496](https://github.com/grafana/grafana/pull/96496), [@ppcano](https://github.com/ppcano)
|
||||
- **Alerting:** Improve performance ash page [#97619](https://github.com/grafana/grafana/pull/97619), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
|
||||
- **Alerting:** Make alert rule policies preview use k8s API [#97070](https://github.com/grafana/grafana/pull/97070), [@tomratcliffe](https://github.com/tomratcliffe)
|
||||
- **Alerting:** Return default builtin templates in k8s templategroup API and UI [#96330](https://github.com/grafana/grafana/pull/96330), [@JacobsonMT](https://github.com/JacobsonMT)
|
||||
- **Alerting:** Simplify notification step [#96430](https://github.com/grafana/grafana/pull/96430), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
|
||||
- **Alerting:** Update state manager to take image only once per rule evaluation [#98289](https://github.com/grafana/grafana/pull/98289), [@yuri-tceretian](https://github.com/yuri-tceretian)
|
||||
- **Analytics Views:** Deprecate :dashboardID endpoints in favor of uid/:dashboardUID (Enterprise)
|
||||
- **Analytics:** Summaries: Deprecate dashboard_id endpoints in favor of dashboard_uid (Enterprise)
|
||||
- **Announcement Banners:** Enable feature for all cloud tiers (Enterprise)
|
||||
- **Announcement banner:** Remove feature toggle [#98782](https://github.com/grafana/grafana/pull/98782), [@Clarity-89](https://github.com/Clarity-89)
|
||||
- **Announcement banner:** Remove feature toggle (Enterprise)
|
||||
- **Announcement banner:** Sort by last updated (Enterprise)
|
||||
- **Auth:** Return error when retries have been exhausted for OAuth token refresh [#98034](https://github.com/grafana/grafana/pull/98034), [@mgyongyosi](https://github.com/mgyongyosi)
|
||||
- **Azure Monitor:** Add a feature flag to toggle user auth for Azure Monitor only [#96858](https://github.com/grafana/grafana/pull/96858), [@adamyeats](https://github.com/adamyeats)
|
||||
- **Azure:** Improve Azure Prometheus exemplars UI/UX [#97198](https://github.com/grafana/grafana/pull/97198), [@aangelisc](https://github.com/aangelisc)
|
||||
- **Azure:** Unify credentials in frontend for Prometheus [#96568](https://github.com/grafana/grafana/pull/96568), [@yjsong11](https://github.com/yjsong11)
|
||||
- **Chore:** Bump Go to 1.23.4 [#98853](https://github.com/grafana/grafana/pull/98853), [@Proximyst](https://github.com/Proximyst)
|
||||
- **Chore:** Bump Go to 1.23.4 (Enterprise)
|
||||
- **Chore:** Remove experimental Storage UI [#96887](https://github.com/grafana/grafana/pull/96887), [@ryantxu](https://github.com/ryantxu)
|
||||
- **Chore:** Update to node 22 [#97779](https://github.com/grafana/grafana/pull/97779), [@ashharrison90](https://github.com/ashharrison90)
|
||||
- **CloudMigrations:** Enable feature toggle by default in 11.5 [#98686](https://github.com/grafana/grafana/pull/98686), [@mmandrus](https://github.com/mmandrus)
|
||||
- **CloudMigrations:** Introduce RBAC role for migration assistant [#98588](https://github.com/grafana/grafana/pull/98588), [@macabu](https://github.com/macabu)
|
||||
- **CloudWatch:** Add OpenSearch PPL and SQL support in Logs Insights [#97508](https://github.com/grafana/grafana/pull/97508), [@idastambuk](https://github.com/idastambuk)
|
||||
- **CloudWatch:** Batch different time ranges separately [#98230](https://github.com/grafana/grafana/pull/98230), [@iwysiu](https://github.com/iwysiu)
|
||||
- **Cloudwatch:** Accept empty string for logstimeout and mark errors downstream [#96947](https://github.com/grafana/grafana/pull/96947), [@iwysiu](https://github.com/iwysiu)
|
||||
- **Cloudwatch:** Update grafana-aws-sdk for AWS/AmplifyHosting metrics [#97799](https://github.com/grafana/grafana/pull/97799), [@iwysiu](https://github.com/iwysiu)
|
||||
- **Dashboard Scene:** Shows usages in variables list [#96000](https://github.com/grafana/grafana/pull/96000), [@harisrozajac](https://github.com/harisrozajac)
|
||||
- **Dashboards:** Add option to specify explicit percent change text size for stat panels [#96952](https://github.com/grafana/grafana/pull/96952), [@XZCendence](https://github.com/XZCendence)
|
||||
- **Dashboards:** Allow DashboardDS subqueries in MixedDS [#97116](https://github.com/grafana/grafana/pull/97116), [@mdvictor](https://github.com/mdvictor)
|
||||
- **Dashboards:** Update docs of the `overwrite` param in Save Dashboard API Call [#97011](https://github.com/grafana/grafana/pull/97011), [@ArturWierzbicki](https://github.com/ArturWierzbicki)
|
||||
- **Datasources:** Add toggle to control default behaviour of 'Manage alerts via Alerts UI' toggle [#98441](https://github.com/grafana/grafana/pull/98441), [@macabu](https://github.com/macabu)
|
||||
- **Datasources:** Allow clearing trace to logs, metrics and profiles datasource pickers [#96554](https://github.com/grafana/grafana/pull/96554), [@adrapereira](https://github.com/adrapereira)
|
||||
- **Docker:** Don't use legacy ENV syntax [#93218](https://github.com/grafana/grafana/pull/93218), [@simPod](https://github.com/simPod)
|
||||
- **Elasticsearch:** Health endpoint should handle http errors [#96803](https://github.com/grafana/grafana/pull/96803), [@iwysiu](https://github.com/iwysiu)
|
||||
- **Elasticsearch:** Use \_field_caps instead of \_mapping to get fields [#97607](https://github.com/grafana/grafana/pull/97607), [@iwysiu](https://github.com/iwysiu)
|
||||
- **Explore Profiles:** Preinstall for onprem Grafana instances [#97775](https://github.com/grafana/grafana/pull/97775), [@ifrost](https://github.com/ifrost)
|
||||
- **Explore metrics:** Consolidate filters with the OTel experience [#98371](https://github.com/grafana/grafana/pull/98371), [@bohandley](https://github.com/bohandley)
|
||||
- **Explore:** Show links to queryless apps [#96625](https://github.com/grafana/grafana/pull/96625), [@ifrost](https://github.com/ifrost)
|
||||
- **Expressions:** Add notification for Strict Mode behavior in Reduce component [#97224](https://github.com/grafana/grafana/pull/97224), [@shubhankarunhale](https://github.com/shubhankarunhale)
|
||||
- **Faro:** Improve performance of TRACKING_URLS regex [#98022](https://github.com/grafana/grafana/pull/98022), [@kpelelis](https://github.com/kpelelis)
|
||||
- **FeatureToggles:** Make newFiltersUI feature toggle generally available [#97460](https://github.com/grafana/grafana/pull/97460), [@Sergej-Vlasov](https://github.com/Sergej-Vlasov)
|
||||
- **Features:** Remove cloudwatchMetricInsightsCrossAccount feature toggle [#98826](https://github.com/grafana/grafana/pull/98826), [@idastambuk](https://github.com/idastambuk)
|
||||
- **Frontend Sandbox:** Add switch to toggle plugins frontend sandbox via catalog UI (Enterprise)
|
||||
- **Graphite:** Set `maxDataPoints` based on user value in alerting [#97178](https://github.com/grafana/grafana/pull/97178), [@aangelisc](https://github.com/aangelisc)
|
||||
- **Licensing:** Tidy up license token database code (Enterprise)
|
||||
- **LoginAttempt:** Add setting to control max number of attempts before user login gets locked [#97091](https://github.com/grafana/grafana/pull/97091), [@kalleep](https://github.com/kalleep)
|
||||
- **Logs Panel:** Add infinite scrolling support for Dashboards and Apps [#97095](https://github.com/grafana/grafana/pull/97095), [@matyax](https://github.com/matyax)
|
||||
- **Logs Panel:** Allow text selection without changing Log Details state [#96995](https://github.com/grafana/grafana/pull/96995), [@matyax](https://github.com/matyax)
|
||||
- **Logs Panel:** Limit displayed characters to MAX_CHARACTERS [#96997](https://github.com/grafana/grafana/pull/96997), [@matyax](https://github.com/matyax)
|
||||
- **Logs:** Added option to show the log line body when displayed fields are used [#97209](https://github.com/grafana/grafana/pull/97209), [@matyax](https://github.com/matyax)
|
||||
- **Logs:** Added support to disable and re-enable the popover menu [#98254](https://github.com/grafana/grafana/pull/98254), [@matyax](https://github.com/matyax)
|
||||
- **Logs:** Allow scroll to reach the bottom of the log list before loading more [#96668](https://github.com/grafana/grafana/pull/96668), [@matyax](https://github.com/matyax)
|
||||
- **Loki:** Added support for disabled operations in Query Builder [#96751](https://github.com/grafana/grafana/pull/96751), [@matyax](https://github.com/matyax)
|
||||
- **Loki:** Added support to show label types in Log Details [#97284](https://github.com/grafana/grafana/pull/97284), [@matyax](https://github.com/matyax)
|
||||
- **Loki:** Allow regex in `label` derived field [#96609](https://github.com/grafana/grafana/pull/96609), [@svennergr](https://github.com/svennergr)
|
||||
- **Loki:** Hide internal labels [#97323](https://github.com/grafana/grafana/pull/97323), [@svennergr](https://github.com/svennergr)
|
||||
- **Loki:** Sync query direction with sort order in Explore and Dashboards [#98722](https://github.com/grafana/grafana/pull/98722), [@matyax](https://github.com/matyax)
|
||||
- **OAuth:** Support client_secret_jwt for oauth providers when doing token exchange [#95455](https://github.com/grafana/grafana/pull/95455), [@naizerjohn-ms](https://github.com/naizerjohn-ms)
|
||||
- **OAuth:** Use the attached external session data in OAuthToken and OAuthTokenSync [#96655](https://github.com/grafana/grafana/pull/96655), [@mgyongyosi](https://github.com/mgyongyosi)
|
||||
- **Org Selection:** Show correct selected org when select is open [#96601](https://github.com/grafana/grafana/pull/96601), [@yincongcyincong](https://github.com/yincongcyincong)
|
||||
- **PDF:** Add new zoom options (Enterprise)
|
||||
- **Plugin Extensions:** Only load app plugins when necessary [#86624](https://github.com/grafana/grafana/pull/86624), [@leventebalogh](https://github.com/leventebalogh)
|
||||
- **Plugins:** Add token to gcom requests [#96261](https://github.com/grafana/grafana/pull/96261), [@oshirohugo](https://github.com/oshirohugo)
|
||||
- **Plugins:** Add token to gcom requests (Enterprise)
|
||||
- **Plugins:** Disable version install when angular version is not supported [#97189](https://github.com/grafana/grafana/pull/97189), [@oshirohugo](https://github.com/oshirohugo)
|
||||
- **Plugins:** Disable version installation for specific plugin types [#98597](https://github.com/grafana/grafana/pull/98597), [@oshirohugo](https://github.com/oshirohugo)
|
||||
- **Plugins:** Update to latest go plugin SDK (v0.260.3) w/ arrow v18 [#97561](https://github.com/grafana/grafana/pull/97561), [@ryantxu](https://github.com/ryantxu)
|
||||
- **Plugins:** Use grafana-com sso_api_token [#97096](https://github.com/grafana/grafana/pull/97096), [@oshirohugo](https://github.com/oshirohugo)
|
||||
- **Plugins:** Use grafana-com sso_api_token (Enterprise)
|
||||
- **Prometheus datasource:** Show info annotations in the UI [#97978](https://github.com/grafana/grafana/pull/97978), [@zenador](https://github.com/zenador)
|
||||
- **Prometheus:** Improve handling of special chars in label values [#96067](https://github.com/grafana/grafana/pull/96067), [@NWRichmond](https://github.com/NWRichmond)
|
||||
- **PublicDashboards:** Remove publicDashboards FF [#96578](https://github.com/grafana/grafana/pull/96578), [@juanicabanas](https://github.com/juanicabanas)
|
||||
- **Reporting:** Add allow list email domain configuration (Enterprise)
|
||||
- **Reporting:** Include the apiserver by default and deprecated internal ids (Enterprise)
|
||||
- **RuntimeDataSource:** Support in core for runtime registered data sources [#93956](https://github.com/grafana/grafana/pull/93956), [@torkelo](https://github.com/torkelo)
|
||||
- **SAML:** Add the ability to specify EntityID (Enterprise)
|
||||
- **SAML:** Implement correct SLO with NameID and SessionIndex handling (Enterprise)
|
||||
- **Security:** Update to Go 1.23.5 - Backport to v11.5.x [#99122](https://github.com/grafana/grafana/pull/99122), [@Proximyst](https://github.com/Proximyst)
|
||||
- **Security:** Update to Go 1.23.5 - Backport to v11.5.x (Enterprise)
|
||||
- **Snapshots:** Add RBAC roles for creating and deleting [#96126](https://github.com/grafana/grafana/pull/96126), [@evictorero](https://github.com/evictorero)
|
||||
- **Storage:** Removes integration tests for MySQL 5.7 since it is EOL [#98013](https://github.com/grafana/grafana/pull/98013), [@inf0rmer](https://github.com/inf0rmer)
|
||||
- **Tempo:** Add support for TraceQL Metrics exemplars [#96859](https://github.com/grafana/grafana/pull/96859), [@adrapereira](https://github.com/adrapereira)
|
||||
- **Tempo:** Honor datasource TLS settings for gRPC requests [#97484](https://github.com/grafana/grafana/pull/97484), [@mdisibio](https://github.com/mdisibio)
|
||||
- **Tempo:** Improve handling of multiple values in the Search tab query generation [#98427](https://github.com/grafana/grafana/pull/98427), [@adrapereira](https://github.com/adrapereira)
|
||||
- **ToolbarButton:** Auto width on smaller screen sizes [#96023](https://github.com/grafana/grafana/pull/96023), [@yincongcyincong](https://github.com/yincongcyincong)
|
||||
- **Trace View:** Set span filters as panel options [#98328](https://github.com/grafana/grafana/pull/98328), [@adrapereira](https://github.com/adrapereira)
|
||||
- **TransformationFilter:** Implement RefID multi picker [#96841](https://github.com/grafana/grafana/pull/96841), [@Sergej-Vlasov](https://github.com/Sergej-Vlasov)
|
||||
- **Transformations:** Add Delimiter format option to Extract fields [#97340](https://github.com/grafana/grafana/pull/97340), [@tskarhed](https://github.com/tskarhed)
|
||||
- **Transformations:** Add RegExp option to Extract fields transformer [#96593](https://github.com/grafana/grafana/pull/96593), [@leeoniya](https://github.com/leeoniya)
|
||||
- **Transformations:** GroupToMatrix add 0 as special value [#97642](https://github.com/grafana/grafana/pull/97642), [@tskarhed](https://github.com/tskarhed)
|
||||
- **Zipkin:** Run queries through backend [#97754](https://github.com/grafana/grafana/pull/97754), [@ivanahuckova](https://github.com/ivanahuckova)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- **Alerting:** AlertingQueryRunner should skip descendant nodes of invalid queries [#97528](https://github.com/grafana/grafana/pull/97528), [@gillesdemey](https://github.com/gillesdemey)
|
||||
- **Alerting:** Allow notification policy filters to match quoted matchers [#98525](https://github.com/grafana/grafana/pull/98525), [@gillesdemey](https://github.com/gillesdemey)
|
||||
- **Alerting:** Fix alert rule list view summaries [#98433](https://github.com/grafana/grafana/pull/98433), [@yincongcyincong](https://github.com/yincongcyincong)
|
||||
- **Alerting:** Fix alert rules unpausing after moving rule to different folder [#97580](https://github.com/grafana/grafana/pull/97580), [@santihernandezc](https://github.com/santihernandezc)
|
||||
- **Alerting:** Fix ash not showing history graph in firefox [#98128](https://github.com/grafana/grafana/pull/98128), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
|
||||
- **Alerting:** Fix bug when saving a rule more than once [#96658](https://github.com/grafana/grafana/pull/96658), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
|
||||
- **Alerting:** Fix data-testid in RuleEditorSection [#97473](https://github.com/grafana/grafana/pull/97473), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
|
||||
- **Alerting:** Fix filtering rule group permissions based on their full path (Enterprise)
|
||||
- **Alerting:** Fix go template parsing [#97145](https://github.com/grafana/grafana/pull/97145), [@konrad147](https://github.com/konrad147)
|
||||
- **Alerting:** Fix label escaping in rule export [#97985](https://github.com/grafana/grafana/pull/97985), [@moustafab](https://github.com/moustafab)
|
||||
- **Alerting:** Fix missing instances and history when Grafana rule is stored in folder with / [#97956](https://github.com/grafana/grafana/pull/97956), [@gillesdemey](https://github.com/gillesdemey)
|
||||
- **Alerting:** Fix navigating to URLs with "%25" [#96992](https://github.com/grafana/grafana/pull/96992), [@gillesdemey](https://github.com/gillesdemey)
|
||||
- **Alerting:** Fix no-change scenario in provisioning rule update API [#98389](https://github.com/grafana/grafana/pull/98389), [@alexander-akhmetov](https://github.com/alexander-akhmetov)
|
||||
- **Alerting:** Fix not being able to remove a reducer when using range query [#97757](https://github.com/grafana/grafana/pull/97757), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
|
||||
- **Alerting:** Fix recording rules rendering simplified condition [#97497](https://github.com/grafana/grafana/pull/97497), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
|
||||
- **Alerting:** Fix removing reducer when inital value is instant [#97054](https://github.com/grafana/grafana/pull/97054), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
|
||||
- **Alerting:** Fix simplified query step [#97046](https://github.com/grafana/grafana/pull/97046), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
|
||||
- **Alerting:** Fix slack image uploading to use new api [#97817](https://github.com/grafana/grafana/pull/97817), [@moustafab](https://github.com/moustafab)
|
||||
- **Alerting:** Fix terraform export of notification policy [#98429](https://github.com/grafana/grafana/pull/98429), [@moustafab](https://github.com/moustafab)
|
||||
- **Alerting:** Fix updating condition when refId changes [#97753](https://github.com/grafana/grafana/pull/97753), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
|
||||
- **Alerting:** Fix using stacks- prefix instead of stack- for checking the namespace in boot data [#97492](https://github.com/grafana/grafana/pull/97492), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
|
||||
- **Anonymous User:** Adds validator service for anonymous users (Enterprise)
|
||||
- **Auth:** Fix SAML user IsExternallySynced not being set correctly [#98487](https://github.com/grafana/grafana/pull/98487), [@volcanonoodle](https://github.com/volcanonoodle)
|
||||
- **Azure Monitor:** Add safety around usage of frame.Meta.Custom struct [#97766](https://github.com/grafana/grafana/pull/97766), [@adamyeats](https://github.com/adamyeats)
|
||||
- **Azure/GCM:** Improve error display [#96921](https://github.com/grafana/grafana/pull/96921), [@aangelisc](https://github.com/aangelisc)
|
||||
- **CloudWatch:** Fix conditions for fetching wildcards [#98648](https://github.com/grafana/grafana/pull/98648), [@iwysiu](https://github.com/iwysiu)
|
||||
- **CloudWatch:** Fix interpolation of log groups when fetching fields [#98054](https://github.com/grafana/grafana/pull/98054), [@idastambuk](https://github.com/idastambuk)
|
||||
- **Dashboard:** Fixes issue with compatability of old DashboardModel.annotations [#97328](https://github.com/grafana/grafana/pull/97328), [@torkelo](https://github.com/torkelo)
|
||||
- **Dashboards:** Fix issue where filtered panels would not react to variable changes [#98718](https://github.com/grafana/grafana/pull/98718), [@oscarkilhed](https://github.com/oscarkilhed)
|
||||
- **Dashboards:** Fixes week relative time ranges when weekStart was changed [#98167](https://github.com/grafana/grafana/pull/98167), [@torkelo](https://github.com/torkelo)
|
||||
- **Dashboards:** Panel react for `timeFrom` and `timeShift` changes using variables [#98510](https://github.com/grafana/grafana/pull/98510), [@Sergej-Vlasov](https://github.com/Sergej-Vlasov)
|
||||
- **DateTimePicker:** Fixes issue with date picker showing invalid date [#97888](https://github.com/grafana/grafana/pull/97888), [@torkelo](https://github.com/torkelo)
|
||||
- **Fix:** Add support for datasource variable queries [#98098](https://github.com/grafana/grafana/pull/98098), [@sunker](https://github.com/sunker)
|
||||
- **Fix:** Do not fetch Orgs if the user is authenticated by apikey/sa or render key [#97162](https://github.com/grafana/grafana/pull/97162), [@mgyongyosi](https://github.com/mgyongyosi)
|
||||
- **Fix:** Double encoding of URLs when using data proxy [#98494](https://github.com/grafana/grafana/pull/98494), [@s4kh](https://github.com/s4kh)
|
||||
- **Font:** Disable contextual font ligatures [#98521](https://github.com/grafana/grafana/pull/98521), [@ashharrison90](https://github.com/ashharrison90)
|
||||
- **GrafanaUI:** Fix inconsistent controlled/uncontrolled state in AutoSizeInput [#96696](https://github.com/grafana/grafana/pull/96696), [@joshhunt](https://github.com/joshhunt)
|
||||
- **GrafanaUI:** Revert: Fix inconsistent controlled/uncontrolled state in AutoSizeInput [#97551](https://github.com/grafana/grafana/pull/97551), [@itsmylife](https://github.com/itsmylife)
|
||||
- **InfluxDB:** Adhoc filters can use template vars as values [#98567](https://github.com/grafana/grafana/pull/98567), [@bossinc](https://github.com/bossinc)
|
||||
- **Library Panel:** Fix issue where library panels did not display panel links. [#98655](https://github.com/grafana/grafana/pull/98655), [@yincongcyincong](https://github.com/yincongcyincong)
|
||||
- **LibraryPanel:** Fallback to panel title if library panel title is not set [#99411](https://github.com/grafana/grafana/pull/99411), [@ivanortegaalba](https://github.com/ivanortegaalba)
|
||||
- **Loki:** Fix a bug when reading frames without values but warnings [#97197](https://github.com/grafana/grafana/pull/97197), [@svennergr](https://github.com/svennergr)
|
||||
- **Loki:** Only hide a set of labels instead of every label starting with `__` [#98730](https://github.com/grafana/grafana/pull/98730), [@svennergr](https://github.com/svennergr)
|
||||
- **Org:** Fix redirection logic to work consistently [#96521](https://github.com/grafana/grafana/pull/96521), [@yincongcyincong](https://github.com/yincongcyincong)
|
||||
- **Panel inspect:** Fix file names of data download included uninterpolated variable names. [#98832](https://github.com/grafana/grafana/pull/98832), [@alexrosenfeld10](https://github.com/alexrosenfeld10)
|
||||
- **Scenes:** Upgrade to 5.36.3 [#98661](https://github.com/grafana/grafana/pull/98661), [@ivanortegaalba](https://github.com/ivanortegaalba)
|
||||
- **Snapshot:** Show proper breadcrumb path [#98806](https://github.com/grafana/grafana/pull/98806), [@ashharrison90](https://github.com/ashharrison90)
|
||||
- **Time Picker:** Fix "Fiscal year start month" selection behaviour [#98576](https://github.com/grafana/grafana/pull/98576), [@ashharrison90](https://github.com/ashharrison90)
|
||||
- **Unified Storage:** Add support for verify-full in postgres [#96825](https://github.com/grafana/grafana/pull/96825), [@chaudyg](https://github.com/chaudyg)
|
||||
- **Unified Storage:** Use tls preferred when grafana db using ssl [#97378](https://github.com/grafana/grafana/pull/97378), [@owensmallwood](https://github.com/owensmallwood)
|
||||
- **Usage Insights:** Fix usage insight errors being logged as [object Object] [#93502](https://github.com/grafana/grafana/pull/93502), [@mmandrus](https://github.com/mmandrus)
|
||||
|
||||
### Breaking changes
|
||||
|
||||
- **Loki:** Default to `/labels` API with `query` param instead of `/series` API [#97935](https://github.com/grafana/grafana/pull/97935), [@svennergr](https://github.com/svennergr)
|
||||
|
||||
### Plugin development fixes & changes
|
||||
|
||||
- **Grafana UI:** Re-add react-router-dom as a dependency [#97540](https://github.com/grafana/grafana/pull/97540), [@leventebalogh](https://github.com/leventebalogh)
|
||||
|
||||
<!-- 11.5.0 END -->
|
||||
<!-- 11.4.1 START -->
|
||||
|
||||
# 11.4.1 (2025-01-28)
|
||||
|
||||
### Features and enhancements
|
||||
|
||||
- **Security:** Update to Go 1.23.5 - Backport to v11.4.x [#99123](https://github.com/grafana/grafana/pull/99123), [@Proximyst](https://github.com/Proximyst)
|
||||
- **Security:** Update to Go 1.23.5 - Backport to v11.4.x (Enterprise)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- **Alerting:** AlertingQueryRunner should skip descendant nodes of invalid queries [#97830](https://github.com/grafana/grafana/pull/97830), [@gillesdemey](https://github.com/gillesdemey)
|
||||
- **Alerting:** Fix alert rules unpausing after moving rule to different folder [#97583](https://github.com/grafana/grafana/pull/97583), [@santihernandezc](https://github.com/santihernandezc)
|
||||
- **Alerting:** Fix label escaping in rule export [#98649](https://github.com/grafana/grafana/pull/98649), [@moustafab](https://github.com/moustafab)
|
||||
- **Alerting:** Fix slack image uploading to use new api [#98066](https://github.com/grafana/grafana/pull/98066), [@moustafab](https://github.com/moustafab)
|
||||
- **Azure/GCM:** Improve error display [#97594](https://github.com/grafana/grafana/pull/97594), [@aangelisc](https://github.com/aangelisc)
|
||||
- **Dashboards:** Fix issue where filtered panels would not react to variable changes [#98734](https://github.com/grafana/grafana/pull/98734), [@oscarkilhed](https://github.com/oscarkilhed)
|
||||
- **Dashboards:** Fixes issue with panel header showing even when hide time override was enabled [#98747](https://github.com/grafana/grafana/pull/98747), [@torkelo](https://github.com/torkelo)
|
||||
- **Dashboards:** Fixes week relative time ranges when weekStart was changed [#98269](https://github.com/grafana/grafana/pull/98269), [@torkelo](https://github.com/torkelo)
|
||||
- **Dashboards:** Panel react for `timeFrom` and `timeShift` changes using variables [#98659](https://github.com/grafana/grafana/pull/98659), [@Sergej-Vlasov](https://github.com/Sergej-Vlasov)
|
||||
- **DateTimePicker:** Fixes issue with date picker showing invalid date [#97971](https://github.com/grafana/grafana/pull/97971), [@torkelo](https://github.com/torkelo)
|
||||
- **Fix:** Add support for datasource variable queries [#98119](https://github.com/grafana/grafana/pull/98119), [@sunker](https://github.com/sunker)
|
||||
- **InfluxDB:** Adhoc filters can use template vars as values [#98786](https://github.com/grafana/grafana/pull/98786), [@bossinc](https://github.com/bossinc)
|
||||
- **LibraryPanel:** Fallback to panel title if library panel title is not set [#99410](https://github.com/grafana/grafana/pull/99410), [@ivanortegaalba](https://github.com/ivanortegaalba)
|
||||
|
||||
### Plugin development fixes & changes
|
||||
|
||||
- **Grafana UI:** Re-add react-router-dom as a dependency [#98422](https://github.com/grafana/grafana/pull/98422), [@leventebalogh](https://github.com/leventebalogh)
|
||||
|
||||
<!-- 11.4.1 END -->
|
||||
<!-- 11.3.3 START -->
|
||||
|
||||
# 11.3.3 (2025-01-28)
|
||||
|
||||
### Features and enhancements
|
||||
|
||||
- **Azure Monitor:** Add a feature flag to toggle user auth for Azure Monitor only [#97576](https://github.com/grafana/grafana/pull/97576), [@adamyeats](https://github.com/adamyeats)
|
||||
- **Security:** Update to Go 1.23.5 - Backport to v11.3.x [#99124](https://github.com/grafana/grafana/pull/99124), [@Proximyst](https://github.com/Proximyst)
|
||||
- **Security:** Update to Go 1.23.5 - Backport to v11.3.x (Enterprise)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- **Alerting:** AlertingQueryRunner should skip descendant nodes of invalid queries [#97829](https://github.com/grafana/grafana/pull/97829), [@gillesdemey](https://github.com/gillesdemey)
|
||||
- **Azure/GCM:** Improve error display [#97593](https://github.com/grafana/grafana/pull/97593), [@aangelisc](https://github.com/aangelisc)
|
||||
- **Dashboard:** Fixes issue with compatability of old DashboardModel.annotations [#97467](https://github.com/grafana/grafana/pull/97467), [@torkelo](https://github.com/torkelo)
|
||||
- **Dashboards:** Fix issue where filtered panels would not react to variable changes [#98733](https://github.com/grafana/grafana/pull/98733), [@oscarkilhed](https://github.com/oscarkilhed)
|
||||
- **Dashboards:** Fixes issue with panel header showing even when hide time override was enabled [#97389](https://github.com/grafana/grafana/pull/97389), [@torkelo](https://github.com/torkelo)
|
||||
- **Dashboards:** Fixes week relative time ranges when weekStart was changed [#98268](https://github.com/grafana/grafana/pull/98268), [@torkelo](https://github.com/torkelo)
|
||||
- **DateTimePicker:** Fixes issue with date picker showing invalid date [#97970](https://github.com/grafana/grafana/pull/97970), [@torkelo](https://github.com/torkelo)
|
||||
- **Fix:** Add support for datasource variable queries [#98118](https://github.com/grafana/grafana/pull/98118), [@sunker](https://github.com/sunker)
|
||||
- **InfluxDB:** Adhoc filters can use template vars as values [#98785](https://github.com/grafana/grafana/pull/98785), [@bossinc](https://github.com/bossinc)
|
||||
- **Unified Storage:** Use tls preferred when grafana db using ssl [#97379](https://github.com/grafana/grafana/pull/97379), [@owensmallwood](https://github.com/owensmallwood)
|
||||
|
||||
### Plugin development fixes & changes
|
||||
|
||||
- **Grafana UI:** Re-add react-router-dom as a dependency [#98421](https://github.com/grafana/grafana/pull/98421), [@leventebalogh](https://github.com/leventebalogh)
|
||||
|
||||
<!-- 11.3.3 END -->
|
||||
<!-- 11.2.6 START -->
|
||||
|
||||
# 11.2.6 (2025-01-28)
|
||||
|
||||
### Features and enhancements
|
||||
|
||||
- **Azure Monitor:** Add a feature flag to toggle user auth for Azure Monitor only [#97565](https://github.com/grafana/grafana/pull/97565), [@adamyeats](https://github.com/adamyeats)
|
||||
- **Security:** Update to Go 1.22.11 - Backport to v11.2.x [#99125](https://github.com/grafana/grafana/pull/99125), [@Proximyst](https://github.com/Proximyst)
|
||||
- **Security:** Update to Go 1.22.11 - Backport to v11.2.x (Enterprise)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- **Azure/GCM:** Improve error display [#97591](https://github.com/grafana/grafana/pull/97591), [@aangelisc](https://github.com/aangelisc)
|
||||
|
||||
<!-- 11.2.6 END -->
|
||||
<!-- 11.1.11 START -->
|
||||
|
||||
# 11.1.11 (2025-01-28)
|
||||
|
||||
### Features and enhancements
|
||||
|
||||
- **Security:** Update to Go 1.22.11 - Backport to v11.1.x [#99126](https://github.com/grafana/grafana/pull/99126), [@Proximyst](https://github.com/Proximyst)
|
||||
- **Security:** Update to Go 1.22.11 - Backport to v11.1.x (Enterprise)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- **Azure/GCM:** Improve error display [#97595](https://github.com/grafana/grafana/pull/97595), [@aangelisc](https://github.com/aangelisc)
|
||||
|
||||
<!-- 11.1.11 END -->
|
||||
<!-- 11.0.10 START -->
|
||||
|
||||
# 11.0.10 (2025-01-28)
|
||||
|
||||
### Features and enhancements
|
||||
|
||||
- **Security:** Update to Go 1.22.11 - Backport to v11.0.x [#99127](https://github.com/grafana/grafana/pull/99127), [@Proximyst](https://github.com/Proximyst)
|
||||
- **Security:** Update to Go 1.22.11 - Backport to v11.0.x (Enterprise)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- **Azure/GCM:** Improve error display [#97592](https://github.com/grafana/grafana/pull/97592), [@aangelisc](https://github.com/aangelisc)
|
||||
|
||||
<!-- 11.0.10 END -->
|
||||
<!-- 10.4.15 START -->
|
||||
|
||||
# 10.4.15 (2025-01-28)
|
||||
|
||||
### Features and enhancements
|
||||
|
||||
- **Security:** Update to Go 1.22.11 - Backport to v10.4.x [#99128](https://github.com/grafana/grafana/pull/99128), [@Proximyst](https://github.com/Proximyst)
|
||||
- **Security:** Update to Go 1.22.11 - Backport to v10.4.x (Enterprise)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- **Azure/GCM:** Improve error display [#97590](https://github.com/grafana/grafana/pull/97590), [@aangelisc](https://github.com/aangelisc)
|
||||
|
||||
<!-- 10.4.15 END -->
|
||||
<!-- 11.4.0 START -->
|
||||
|
||||
# 11.4.0 (2024-12-05)
|
||||
|
||||
77
Dockerfile
77
Dockerfile
@@ -1,13 +1,19 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
# to maintain formatting of multiline commands in vscode, add the following to settings.json:
|
||||
# "docker.languageserver.formatter.ignoreMultilineInstructions": true
|
||||
|
||||
ARG BASE_IMAGE=alpine:3.20
|
||||
ARG JS_IMAGE=node:22-alpine
|
||||
ARG JS_PLATFORM=linux/amd64
|
||||
ARG GO_IMAGE=golang:1.23.1-alpine
|
||||
ARG GO_IMAGE=golang:1.23.5-alpine
|
||||
|
||||
# Default to building locally
|
||||
ARG GO_SRC=go-builder
|
||||
ARG JS_SRC=js-builder
|
||||
|
||||
FROM --platform=${JS_PLATFORM} ${JS_IMAGE} as js-builder
|
||||
# Javascript build stage
|
||||
FROM --platform=${JS_PLATFORM} ${JS_IMAGE} AS js-builder
|
||||
|
||||
ENV NODE_OPTIONS=--max_old_space_size=8000
|
||||
|
||||
@@ -16,7 +22,6 @@ WORKDIR /tmp/grafana
|
||||
COPY package.json project.json nx.json yarn.lock .yarnrc.yml ./
|
||||
COPY .yarn .yarn
|
||||
COPY packages packages
|
||||
COPY plugins-bundled plugins-bundled
|
||||
COPY public public
|
||||
COPY LICENSE ./
|
||||
COPY conf/defaults.ini ./conf/defaults.ini
|
||||
@@ -33,7 +38,8 @@ COPY emails emails
|
||||
ENV NODE_ENV=production
|
||||
RUN yarn build
|
||||
|
||||
FROM ${GO_IMAGE} as go-builder
|
||||
# Golang build stage
|
||||
FROM ${GO_IMAGE} AS go-builder
|
||||
|
||||
ARG COMMIT_SHA=""
|
||||
ARG BUILD_BRANCH=""
|
||||
@@ -56,23 +62,24 @@ COPY go.* ./
|
||||
COPY .bingo .bingo
|
||||
|
||||
# Include vendored dependencies
|
||||
COPY pkg/util/xorm/go.* pkg/util/xorm/
|
||||
COPY pkg/apiserver/go.* pkg/apiserver/
|
||||
COPY pkg/apimachinery/go.* pkg/apimachinery/
|
||||
COPY pkg/build/go.* pkg/build/
|
||||
COPY pkg/build/wire/go.* pkg/build/wire/
|
||||
COPY pkg/promlib/go.* pkg/promlib/
|
||||
COPY pkg/storage/unified/resource/go.* pkg/storage/unified/resource/
|
||||
COPY pkg/storage/unified/apistore/go.* pkg/storage/unified/apistore/
|
||||
COPY pkg/semconv/go.* pkg/semconv/
|
||||
COPY pkg/aggregator/go.* pkg/aggregator/
|
||||
COPY apps/playlist/go.* apps/playlist/
|
||||
COPY apps/investigation/go.* apps/investigation/
|
||||
COPY pkg/util/xorm pkg/util/xorm
|
||||
COPY pkg/apiserver pkg/apiserver
|
||||
COPY pkg/apimachinery pkg/apimachinery
|
||||
COPY pkg/build pkg/build
|
||||
COPY pkg/build/wire pkg/build/wire
|
||||
COPY pkg/promlib pkg/promlib
|
||||
COPY pkg/storage/unified/resource pkg/storage/unified/resource
|
||||
COPY pkg/storage/unified/apistore pkg/storage/unified/apistore
|
||||
COPY pkg/semconv pkg/semconv
|
||||
COPY pkg/aggregator pkg/aggregator
|
||||
COPY apps/playlist apps/playlist
|
||||
COPY apps/investigations apps/investigations
|
||||
COPY apps/advisor apps/advisor
|
||||
COPY apps apps
|
||||
COPY kindsv2 kindsv2
|
||||
COPY apps/alerting/notifications/go.* apps/alerting/notifications/
|
||||
COPY pkg/codegen/go.* pkg/codegen/
|
||||
COPY pkg/plugins/codegen/go.* pkg/plugins/codegen/
|
||||
COPY apps/alerting/notifications apps/alerting/notifications
|
||||
COPY pkg/codegen pkg/codegen
|
||||
COPY pkg/plugins/codegen pkg/plugins/codegen
|
||||
|
||||
RUN go mod download
|
||||
RUN if [[ "$BINGO" = "true" ]]; then \
|
||||
@@ -97,7 +104,8 @@ ENV BUILD_BRANCH=${BUILD_BRANCH}
|
||||
|
||||
RUN make build-go GO_BUILD_TAGS=${GO_BUILD_TAGS} WIRE_TAGS=${WIRE_TAGS}
|
||||
|
||||
FROM ${BASE_IMAGE} as tgz-builder
|
||||
# From-tarball build stage
|
||||
FROM ${BASE_IMAGE} AS tgz-builder
|
||||
|
||||
WORKDIR /tmp/grafana
|
||||
|
||||
@@ -109,8 +117,8 @@ COPY ${GRAFANA_TGZ} /tmp/grafana.tar.gz
|
||||
RUN tar x -z -f /tmp/grafana.tar.gz --strip-components=1
|
||||
|
||||
# helpers for COPY --from
|
||||
FROM ${GO_SRC} as go-src
|
||||
FROM ${JS_SRC} as js-src
|
||||
FROM ${GO_SRC} AS go-src
|
||||
FROM ${JS_SRC} AS js-src
|
||||
|
||||
# Final stage
|
||||
FROM ${BASE_IMAGE}
|
||||
@@ -145,19 +153,20 @@ RUN if grep -i -q alpine /etc/issue; then \
|
||||
fi
|
||||
|
||||
# glibc support for alpine x86_64 only
|
||||
# docker run --rm --env STDOUT=1 sgerrand/glibc-builder 2.40 /usr/glibc-compat > glibc-bin-2.40.tar.gz
|
||||
ARG GLIBC_VERSION=2.40
|
||||
|
||||
RUN if grep -i -q alpine /etc/issue && [ `arch` = "x86_64" ]; then \
|
||||
wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub && \
|
||||
wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.35-r0/glibc-2.35-r0.apk \
|
||||
-O /tmp/glibc-2.35-r0.apk && \
|
||||
wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.35-r0/glibc-bin-2.35-r0.apk \
|
||||
-O /tmp/glibc-bin-2.35-r0.apk && \
|
||||
apk add --force-overwrite --no-cache /tmp/glibc-2.35-r0.apk /tmp/glibc-bin-2.35-r0.apk && \
|
||||
rm -f /lib64/ld-linux-x86-64.so.2 && \
|
||||
ln -s /usr/glibc-compat/lib64/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2 && \
|
||||
rm -f /tmp/glibc-2.35-r0.apk && \
|
||||
rm -f /tmp/glibc-bin-2.35-r0.apk && \
|
||||
rm -f /lib/ld-linux-x86-64.so.2 && \
|
||||
rm -f /etc/ld.so.cache; \
|
||||
wget -qO- "https://dl.grafana.com/glibc/glibc-bin-$GLIBC_VERSION.tar.gz" | tar zxf - -C / \
|
||||
usr/glibc-compat/lib/ld-linux-x86-64.so.2 \
|
||||
usr/glibc-compat/lib/libc.so.6 \
|
||||
usr/glibc-compat/lib/libdl.so.2 \
|
||||
usr/glibc-compat/lib/libm.so.6 \
|
||||
usr/glibc-compat/lib/libpthread.so.0 \
|
||||
usr/glibc-compat/lib/librt.so.1 \
|
||||
usr/glibc-compat/lib/libresolv.so.2 && \
|
||||
mkdir /lib64 && \
|
||||
ln -s /usr/glibc-compat/lib/ld-linux-x86-64.so.2 /lib64; \
|
||||
fi
|
||||
|
||||
COPY --from=go-src /tmp/grafana/conf ./conf
|
||||
|
||||
@@ -8,4 +8,4 @@
|
||||
- @davkal
|
||||
- Docs:
|
||||
- @chri2547
|
||||
- @brendamuir
|
||||
- @JohnnyK-Grafana
|
||||
|
||||
14
Makefile
14
Makefile
@@ -8,7 +8,7 @@ WIRE_TAGS = "oss"
|
||||
include .bingo/Variables.mk
|
||||
|
||||
GO = go
|
||||
GO_VERSION = 1.23.4
|
||||
GO_VERSION = 1.23.5
|
||||
GO_LINT_FILES ?= $(shell ./scripts/go-workspace/golangci-lint-includes.sh)
|
||||
GO_TEST_FILES ?= $(shell ./scripts/go-workspace/test-includes.sh)
|
||||
SH_FILES ?= $(shell find ./scripts -name *.sh)
|
||||
@@ -149,7 +149,7 @@ gen-cue: ## Do all CUE/Thema code generation
|
||||
.PHONY: gen-cuev2
|
||||
gen-cuev2: ## Do all CUE code generation
|
||||
@echo "generate code from .cue files (v2)"
|
||||
go generate ./kindsv2/gen.go
|
||||
@$(MAKE) -C ./kindsv2 all
|
||||
|
||||
.PHONY: gen-feature-toggles
|
||||
gen-feature-toggles:
|
||||
@@ -211,7 +211,6 @@ build-cli: ## Build Grafana CLI application.
|
||||
build-js: ## Build frontend assets.
|
||||
@echo "build frontend"
|
||||
yarn run build
|
||||
yarn run plugins:build-bundled
|
||||
|
||||
PLUGIN_ID ?=
|
||||
|
||||
@@ -272,6 +271,14 @@ test-go-integration-alertmanager: ## Run integration tests for the remote alertm
|
||||
AM_URL=http://localhost:8080 AM_TENANT_ID=test \
|
||||
$(GO) test $(GO_RACE_FLAG) -count=1 -run "^TestIntegrationRemoteAlertmanager" -covermode=atomic -timeout=5m ./pkg/services/ngalert/...
|
||||
|
||||
.PHONY: test-go-integration-grafana-alertmanager
|
||||
test-go-integration-grafana-alertmanager: ## Run integration tests for the grafana alertmanager
|
||||
@echo "test grafana alertmanager integration tests"
|
||||
@export GRAFANA_VERSION=11.5.0-81938; \
|
||||
$(GO) run tools/setup_grafana_alertmanager_integration_test_images.go; \
|
||||
$(GO) clean -testcache; \
|
||||
$(GO) test $(GO_RACE_FLAG) -count=1 -run "^TestAlertmanagerIntegration" -covermode=atomic -timeout=10m ./pkg/tests/alertmanager/...
|
||||
|
||||
.PHONY: test-go-integration-postgres
|
||||
test-go-integration-postgres: devenv-postgres ## Run integration tests for postgres backend with flags.
|
||||
@echo "test backend integration postgres tests"
|
||||
@@ -422,6 +429,7 @@ protobuf: ## Compile protobuf definitions
|
||||
buf generate pkg/plugins/backendplugin/secretsmanagerplugin --template pkg/plugins/backendplugin/secretsmanagerplugin/buf.gen.yaml
|
||||
buf generate pkg/storage/unified/resource --template pkg/storage/unified/resource/buf.gen.yaml
|
||||
buf generate pkg/services/authz/proto/v1 --template pkg/services/authz/proto/v1/buf.gen.yaml
|
||||
buf generate pkg/services/ngalert/store/proto/v1 --template pkg/services/ngalert/store/proto/v1/buf.gen.yaml
|
||||
|
||||
.PHONY: clean
|
||||
clean: ## Clean up intermediate build artifacts.
|
||||
|
||||
@@ -43,7 +43,7 @@ If you're interested in contributing to the Grafana project:
|
||||
- If you have a specific question, check out our [discussion forums](https://community.grafana.com/).
|
||||
- For general discussions, join us on the [official Slack](https://slack.grafana.com) team.
|
||||
|
||||
This project is tested with [BrowserStack](https://www.browserstack.com/)
|
||||
This project is tested with [BrowserStack](https://www.browserstack.com/).
|
||||
|
||||
## License
|
||||
|
||||
|
||||
1
apps/advisor/.gitignore
vendored
Normal file
1
apps/advisor/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
plugin/src
|
||||
3
apps/advisor/Makefile
Normal file
3
apps/advisor/Makefile
Normal file
@@ -0,0 +1,3 @@
|
||||
.PHONY: generate
|
||||
generate:
|
||||
@grafana-app-sdk generate -g ./pkg/apis --grouping=group --postprocess --defencoding=none
|
||||
@@ -1,9 +1,9 @@
|
||||
module github.com/grafana/grafana/apps/investigation
|
||||
module github.com/grafana/grafana/apps/advisor
|
||||
|
||||
go 1.23.1
|
||||
go 1.23.4
|
||||
|
||||
require (
|
||||
github.com/grafana/grafana-app-sdk v0.23.1
|
||||
github.com/grafana/grafana-app-sdk v0.31.0
|
||||
k8s.io/apimachinery v0.32.0
|
||||
k8s.io/klog/v2 v2.130.1
|
||||
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f
|
||||
@@ -29,8 +29,10 @@ require (
|
||||
github.com/google/gnostic-models v0.6.8 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 // indirect
|
||||
github.com/grafana/grafana-app-sdk/logging v0.29.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/invopop/yaml v0.3.1 // indirect
|
||||
@@ -58,17 +60,18 @@ require (
|
||||
go.opentelemetry.io/otel/metric v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.33.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.4.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
|
||||
golang.org/x/net v0.34.0 // indirect
|
||||
golang.org/x/oauth2 v0.25.0 // indirect
|
||||
golang.org/x/sync v0.10.0 // indirect
|
||||
golang.org/x/sys v0.29.0 // indirect
|
||||
golang.org/x/term v0.28.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
golang.org/x/time v0.9.0 // indirect
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d // indirect
|
||||
google.golang.org/grpc v1.69.2 // indirect
|
||||
google.golang.org/grpc v1.69.4 // indirect
|
||||
google.golang.org/protobuf v1.36.1 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
@@ -29,6 +29,8 @@ github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF
|
||||
github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
|
||||
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
|
||||
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||
github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
|
||||
github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
@@ -43,12 +45,16 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg=
|
||||
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/grafana/grafana-app-sdk v0.23.1 h1:BRpUG0bA0oVxjthkmO2thuJBo3nbjaRSSmZJHw+mA8I=
|
||||
github.com/grafana/grafana-app-sdk v0.23.1/go.mod h1:KzgPnTJfMeckGmMctv6CJb8Jr/o/5rwARDyjXoeR0Fc=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 h1:TmHmbvxPmaegwhDubVz0lICL0J5Ka2vwTzhoePEXsGE=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0/go.mod h1:qztMSjm835F2bXf+5HKAPIS5qsmQDqZna/PgVt4rWtI=
|
||||
github.com/grafana/grafana-app-sdk v0.30.0 h1:Hqn2pETu2mQ4RpWkZYEQfu01P7xd1Z1Gj+HX/8aB0tw=
|
||||
github.com/grafana/grafana-app-sdk v0.30.0/go.mod h1:jhfqNIovb+Mes2vdMf9iMCWQkp1GTNtyNuExONtiNuk=
|
||||
github.com/grafana/grafana-app-sdk/logging v0.29.0 h1:mgbXaAf33aFwqwGVeaX30l8rkeAJH0iACgX5Rn6YkN4=
|
||||
github.com/grafana/grafana-app-sdk/logging v0.29.0/go.mod h1:xy6ZyVXl50Z3DBDLybvBPphbykPhuVNed/VNmen9DQM=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 h1:VNqngBF40hVlDloBruUehVYC3ArSgIyScOAyMRqBxRg=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1/go.mod h1:RBRO7fro65R6tjKzYgLAFo0t1QEXY1Dp+i/bvpRiqiQ=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
@@ -81,6 +87,10 @@ github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM=
|
||||
github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
|
||||
github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4=
|
||||
github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
|
||||
github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s=
|
||||
github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
@@ -130,8 +140,8 @@ go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4Jjx
|
||||
go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8=
|
||||
go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s=
|
||||
go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck=
|
||||
go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg=
|
||||
go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
@@ -150,6 +160,8 @@ golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbht
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -167,18 +179,20 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE=
|
||||
golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484 h1:ChAdCYNQFDk5fYvFZMywKLIijG7TC2m1C2CMEu11G3o=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484/go.mod h1:KRUmxRI4JmbpAm8gcZM4Jsffi859fo5LQjILwuqj9z8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d h1:H8tOf8XM88HvKqLTxe755haY6r1fqqzLbEnfrmLXlSA=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d/go.mod h1:2v7Z7gP2ZUOGsaFyxATQSRoBnKygqVq2Cwnvom7QiqY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d h1:xJJRGY7TJcvIlpSrN3K6LAWgNFUILlO+OMAqtg9aqnw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d/go.mod h1:3ENsm/5D1mzDyhpzeRi1NR784I0BcofWBoSc5QqqMK4=
|
||||
google.golang.org/grpc v1.69.2 h1:U3S9QEtbXC0bYNvRtcoklF3xGtLViumSYxWykJS+7AU=
|
||||
google.golang.org/grpc v1.69.2/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4=
|
||||
google.golang.org/grpc v1.69.4 h1:MF5TftSMkd8GLw/m0KM6V8CMOCY6NZ1NQDPGFgbTt4A=
|
||||
google.golang.org/grpc v1.69.4/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4=
|
||||
google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk=
|
||||
google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
49
apps/advisor/kinds/check.cue
Normal file
49
apps/advisor/kinds/check.cue
Normal file
@@ -0,0 +1,49 @@
|
||||
package advisor
|
||||
|
||||
check: {
|
||||
kind: "Check"
|
||||
pluralName: "Checks"
|
||||
current: "v0alpha1"
|
||||
versions: {
|
||||
"v0alpha1": {
|
||||
codegen: {
|
||||
frontend: true
|
||||
backend: true
|
||||
}
|
||||
validation: {
|
||||
operations: [
|
||||
"CREATE",
|
||||
"UPDATE",
|
||||
]
|
||||
}
|
||||
schema: {
|
||||
#Data: {
|
||||
// Generic data input that a check can receive
|
||||
data?: [string]: string
|
||||
}
|
||||
#ReportFailure: {
|
||||
// Severity of the failure
|
||||
severity: "high" | "low"
|
||||
// Human readable reason for the failure
|
||||
reason: string
|
||||
// Action to take to resolve the failure
|
||||
action: string
|
||||
// Step ID that the failure is associated with
|
||||
stepID: string
|
||||
// Item ID that the failure is associated with
|
||||
itemID: string
|
||||
}
|
||||
#Report: {
|
||||
// Number of elements analyzed
|
||||
count: int
|
||||
// List of failures
|
||||
failures: [...#ReportFailure]
|
||||
}
|
||||
spec: #Data
|
||||
status: {
|
||||
report: #Report
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
26
apps/advisor/kinds/checktype.cue
Normal file
26
apps/advisor/kinds/checktype.cue
Normal file
@@ -0,0 +1,26 @@
|
||||
package advisor
|
||||
|
||||
checktype: {
|
||||
kind: "CheckType"
|
||||
pluralName: "CheckTypes"
|
||||
current: "v0alpha1"
|
||||
versions: {
|
||||
"v0alpha1": {
|
||||
codegen: {
|
||||
frontend: true
|
||||
backend: true
|
||||
}
|
||||
schema: {
|
||||
#Step: {
|
||||
title: string
|
||||
description: string
|
||||
stepID: string
|
||||
}
|
||||
spec: {
|
||||
name: string
|
||||
steps: [...#Step]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
4
apps/advisor/kinds/cue.mod/module.cue
Normal file
4
apps/advisor/kinds/cue.mod/module.cue
Normal file
@@ -0,0 +1,4 @@
|
||||
module: "github.com/grafana/grafana/apps/advisor/kinds"
|
||||
language: {
|
||||
version: "v0.9.0"
|
||||
}
|
||||
10
apps/advisor/kinds/manifest.cue
Normal file
10
apps/advisor/kinds/manifest.cue
Normal file
@@ -0,0 +1,10 @@
|
||||
package advisor
|
||||
|
||||
manifest: {
|
||||
appName: "advisor"
|
||||
groupOverride: "advisor.grafana.app"
|
||||
kinds: [
|
||||
check,
|
||||
checktype,
|
||||
]
|
||||
}
|
||||
28
apps/advisor/pkg/apis/advisor/v0alpha1/check_codec_gen.go
Normal file
28
apps/advisor/pkg/apis/advisor/v0alpha1/check_codec_gen.go
Normal file
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// Code generated by grafana-app-sdk. DO NOT EDIT.
|
||||
//
|
||||
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
|
||||
"github.com/grafana/grafana-app-sdk/resource"
|
||||
)
|
||||
|
||||
// CheckJSONCodec is an implementation of resource.Codec for kubernetes JSON encoding
|
||||
type CheckJSONCodec struct{}
|
||||
|
||||
// Read reads JSON-encoded bytes from `reader` and unmarshals them into `into`
|
||||
func (*CheckJSONCodec) Read(reader io.Reader, into resource.Object) error {
|
||||
return json.NewDecoder(reader).Decode(into)
|
||||
}
|
||||
|
||||
// Write writes JSON-encoded bytes into `writer` marshaled from `from`
|
||||
func (*CheckJSONCodec) Write(writer io.Writer, from resource.Object) error {
|
||||
return json.NewEncoder(writer).Encode(from)
|
||||
}
|
||||
|
||||
// Interface compliance checks
|
||||
var _ resource.Codec = &CheckJSONCodec{}
|
||||
28
apps/advisor/pkg/apis/advisor/v0alpha1/check_metadata_gen.go
Normal file
28
apps/advisor/pkg/apis/advisor/v0alpha1/check_metadata_gen.go
Normal file
@@ -0,0 +1,28 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
time "time"
|
||||
)
|
||||
|
||||
// metadata contains embedded CommonMetadata and can be extended with custom string fields
|
||||
// TODO: use CommonMetadata instead of redefining here; currently needs to be defined here
|
||||
// without external reference as using the CommonMetadata reference breaks thema codegen.
|
||||
type CheckMetadata struct {
|
||||
UpdateTimestamp time.Time `json:"updateTimestamp"`
|
||||
CreatedBy string `json:"createdBy"`
|
||||
Uid string `json:"uid"`
|
||||
CreationTimestamp time.Time `json:"creationTimestamp"`
|
||||
DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty"`
|
||||
Finalizers []string `json:"finalizers"`
|
||||
ResourceVersion string `json:"resourceVersion"`
|
||||
Generation int64 `json:"generation"`
|
||||
UpdatedBy string `json:"updatedBy"`
|
||||
Labels map[string]string `json:"labels"`
|
||||
}
|
||||
|
||||
// NewCheckMetadata creates a new CheckMetadata object.
|
||||
func NewCheckMetadata() *CheckMetadata {
|
||||
return &CheckMetadata{}
|
||||
}
|
||||
266
apps/advisor/pkg/apis/advisor/v0alpha1/check_object_gen.go
Normal file
266
apps/advisor/pkg/apis/advisor/v0alpha1/check_object_gen.go
Normal file
@@ -0,0 +1,266 @@
|
||||
//
|
||||
// Code generated by grafana-app-sdk. DO NOT EDIT.
|
||||
//
|
||||
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/grafana/grafana-app-sdk/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"time"
|
||||
)
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type Check struct {
|
||||
metav1.TypeMeta `json:",inline" yaml:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata" yaml:"metadata"`
|
||||
Spec CheckSpec `json:"spec" yaml:"spec"`
|
||||
CheckStatus CheckStatus `json:"status" yaml:"status"`
|
||||
}
|
||||
|
||||
func (o *Check) GetSpec() any {
|
||||
return o.Spec
|
||||
}
|
||||
|
||||
func (o *Check) SetSpec(spec any) error {
|
||||
cast, ok := spec.(CheckSpec)
|
||||
if !ok {
|
||||
return fmt.Errorf("cannot set spec type %#v, not of type Spec", spec)
|
||||
}
|
||||
o.Spec = cast
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Check) GetSubresources() map[string]any {
|
||||
return map[string]any{
|
||||
"status": o.CheckStatus,
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Check) GetSubresource(name string) (any, bool) {
|
||||
switch name {
|
||||
case "status":
|
||||
return o.CheckStatus, true
|
||||
default:
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Check) SetSubresource(name string, value any) error {
|
||||
switch name {
|
||||
case "status":
|
||||
cast, ok := value.(CheckStatus)
|
||||
if !ok {
|
||||
return fmt.Errorf("cannot set status type %#v, not of type CheckStatus", value)
|
||||
}
|
||||
o.CheckStatus = cast
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("subresource '%s' does not exist", name)
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Check) GetStaticMetadata() resource.StaticMetadata {
|
||||
gvk := o.GroupVersionKind()
|
||||
return resource.StaticMetadata{
|
||||
Name: o.ObjectMeta.Name,
|
||||
Namespace: o.ObjectMeta.Namespace,
|
||||
Group: gvk.Group,
|
||||
Version: gvk.Version,
|
||||
Kind: gvk.Kind,
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Check) SetStaticMetadata(metadata resource.StaticMetadata) {
|
||||
o.Name = metadata.Name
|
||||
o.Namespace = metadata.Namespace
|
||||
o.SetGroupVersionKind(schema.GroupVersionKind{
|
||||
Group: metadata.Group,
|
||||
Version: metadata.Version,
|
||||
Kind: metadata.Kind,
|
||||
})
|
||||
}
|
||||
|
||||
func (o *Check) GetCommonMetadata() resource.CommonMetadata {
|
||||
dt := o.DeletionTimestamp
|
||||
var deletionTimestamp *time.Time
|
||||
if dt != nil {
|
||||
deletionTimestamp = &dt.Time
|
||||
}
|
||||
// Legacy ExtraFields support
|
||||
extraFields := make(map[string]any)
|
||||
if o.Annotations != nil {
|
||||
extraFields["annotations"] = o.Annotations
|
||||
}
|
||||
if o.ManagedFields != nil {
|
||||
extraFields["managedFields"] = o.ManagedFields
|
||||
}
|
||||
if o.OwnerReferences != nil {
|
||||
extraFields["ownerReferences"] = o.OwnerReferences
|
||||
}
|
||||
return resource.CommonMetadata{
|
||||
UID: string(o.UID),
|
||||
ResourceVersion: o.ResourceVersion,
|
||||
Generation: o.Generation,
|
||||
Labels: o.Labels,
|
||||
CreationTimestamp: o.CreationTimestamp.Time,
|
||||
DeletionTimestamp: deletionTimestamp,
|
||||
Finalizers: o.Finalizers,
|
||||
UpdateTimestamp: o.GetUpdateTimestamp(),
|
||||
CreatedBy: o.GetCreatedBy(),
|
||||
UpdatedBy: o.GetUpdatedBy(),
|
||||
ExtraFields: extraFields,
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Check) SetCommonMetadata(metadata resource.CommonMetadata) {
|
||||
o.UID = types.UID(metadata.UID)
|
||||
o.ResourceVersion = metadata.ResourceVersion
|
||||
o.Generation = metadata.Generation
|
||||
o.Labels = metadata.Labels
|
||||
o.CreationTimestamp = metav1.NewTime(metadata.CreationTimestamp)
|
||||
if metadata.DeletionTimestamp != nil {
|
||||
dt := metav1.NewTime(*metadata.DeletionTimestamp)
|
||||
o.DeletionTimestamp = &dt
|
||||
} else {
|
||||
o.DeletionTimestamp = nil
|
||||
}
|
||||
o.Finalizers = metadata.Finalizers
|
||||
if o.Annotations == nil {
|
||||
o.Annotations = make(map[string]string)
|
||||
}
|
||||
if !metadata.UpdateTimestamp.IsZero() {
|
||||
o.SetUpdateTimestamp(metadata.UpdateTimestamp)
|
||||
}
|
||||
if metadata.CreatedBy != "" {
|
||||
o.SetCreatedBy(metadata.CreatedBy)
|
||||
}
|
||||
if metadata.UpdatedBy != "" {
|
||||
o.SetUpdatedBy(metadata.UpdatedBy)
|
||||
}
|
||||
// Legacy support for setting Annotations, ManagedFields, and OwnerReferences via ExtraFields
|
||||
if metadata.ExtraFields != nil {
|
||||
if annotations, ok := metadata.ExtraFields["annotations"]; ok {
|
||||
if cast, ok := annotations.(map[string]string); ok {
|
||||
o.Annotations = cast
|
||||
}
|
||||
}
|
||||
if managedFields, ok := metadata.ExtraFields["managedFields"]; ok {
|
||||
if cast, ok := managedFields.([]metav1.ManagedFieldsEntry); ok {
|
||||
o.ManagedFields = cast
|
||||
}
|
||||
}
|
||||
if ownerReferences, ok := metadata.ExtraFields["ownerReferences"]; ok {
|
||||
if cast, ok := ownerReferences.([]metav1.OwnerReference); ok {
|
||||
o.OwnerReferences = cast
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Check) GetCreatedBy() string {
|
||||
if o.ObjectMeta.Annotations == nil {
|
||||
o.ObjectMeta.Annotations = make(map[string]string)
|
||||
}
|
||||
|
||||
return o.ObjectMeta.Annotations["grafana.com/createdBy"]
|
||||
}
|
||||
|
||||
func (o *Check) SetCreatedBy(createdBy string) {
|
||||
if o.ObjectMeta.Annotations == nil {
|
||||
o.ObjectMeta.Annotations = make(map[string]string)
|
||||
}
|
||||
|
||||
o.ObjectMeta.Annotations["grafana.com/createdBy"] = createdBy
|
||||
}
|
||||
|
||||
func (o *Check) GetUpdateTimestamp() time.Time {
|
||||
if o.ObjectMeta.Annotations == nil {
|
||||
o.ObjectMeta.Annotations = make(map[string]string)
|
||||
}
|
||||
|
||||
parsed, _ := time.Parse(time.RFC3339, o.ObjectMeta.Annotations["grafana.com/updateTimestamp"])
|
||||
return parsed
|
||||
}
|
||||
|
||||
func (o *Check) SetUpdateTimestamp(updateTimestamp time.Time) {
|
||||
if o.ObjectMeta.Annotations == nil {
|
||||
o.ObjectMeta.Annotations = make(map[string]string)
|
||||
}
|
||||
|
||||
o.ObjectMeta.Annotations["grafana.com/updateTimestamp"] = updateTimestamp.Format(time.RFC3339)
|
||||
}
|
||||
|
||||
func (o *Check) GetUpdatedBy() string {
|
||||
if o.ObjectMeta.Annotations == nil {
|
||||
o.ObjectMeta.Annotations = make(map[string]string)
|
||||
}
|
||||
|
||||
return o.ObjectMeta.Annotations["grafana.com/updatedBy"]
|
||||
}
|
||||
|
||||
func (o *Check) SetUpdatedBy(updatedBy string) {
|
||||
if o.ObjectMeta.Annotations == nil {
|
||||
o.ObjectMeta.Annotations = make(map[string]string)
|
||||
}
|
||||
|
||||
o.ObjectMeta.Annotations["grafana.com/updatedBy"] = updatedBy
|
||||
}
|
||||
|
||||
func (o *Check) Copy() resource.Object {
|
||||
return resource.CopyObject(o)
|
||||
}
|
||||
|
||||
func (o *Check) DeepCopyObject() runtime.Object {
|
||||
return o.Copy()
|
||||
}
|
||||
|
||||
// Interface compliance compile-time check
|
||||
var _ resource.Object = &Check{}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type CheckList struct {
|
||||
metav1.TypeMeta `json:",inline" yaml:",inline"`
|
||||
metav1.ListMeta `json:"metadata" yaml:"metadata"`
|
||||
Items []Check `json:"items" yaml:"items"`
|
||||
}
|
||||
|
||||
func (o *CheckList) DeepCopyObject() runtime.Object {
|
||||
return o.Copy()
|
||||
}
|
||||
|
||||
func (o *CheckList) Copy() resource.ListObject {
|
||||
cpy := &CheckList{
|
||||
TypeMeta: o.TypeMeta,
|
||||
Items: make([]Check, len(o.Items)),
|
||||
}
|
||||
o.ListMeta.DeepCopyInto(&cpy.ListMeta)
|
||||
for i := 0; i < len(o.Items); i++ {
|
||||
if item, ok := o.Items[i].Copy().(*Check); ok {
|
||||
cpy.Items[i] = *item
|
||||
}
|
||||
}
|
||||
return cpy
|
||||
}
|
||||
|
||||
func (o *CheckList) GetItems() []resource.Object {
|
||||
items := make([]resource.Object, len(o.Items))
|
||||
for i := 0; i < len(o.Items); i++ {
|
||||
items[i] = &o.Items[i]
|
||||
}
|
||||
return items
|
||||
}
|
||||
|
||||
func (o *CheckList) SetItems(items []resource.Object) {
|
||||
o.Items = make([]Check, len(items))
|
||||
for i := 0; i < len(items); i++ {
|
||||
o.Items[i] = *items[i].(*Check)
|
||||
}
|
||||
}
|
||||
|
||||
// Interface compliance compile-time check
|
||||
var _ resource.ListObject = &CheckList{}
|
||||
34
apps/advisor/pkg/apis/advisor/v0alpha1/check_schema_gen.go
Normal file
34
apps/advisor/pkg/apis/advisor/v0alpha1/check_schema_gen.go
Normal file
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// Code generated by grafana-app-sdk. DO NOT EDIT.
|
||||
//
|
||||
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
"github.com/grafana/grafana-app-sdk/resource"
|
||||
)
|
||||
|
||||
// schema is unexported to prevent accidental overwrites
|
||||
var (
|
||||
schemaCheck = resource.NewSimpleSchema("advisor.grafana.app", "v0alpha1", &Check{}, &CheckList{}, resource.WithKind("Check"),
|
||||
resource.WithPlural("checks"), resource.WithScope(resource.NamespacedScope))
|
||||
kindCheck = resource.Kind{
|
||||
Schema: schemaCheck,
|
||||
Codecs: map[resource.KindEncoding]resource.Codec{
|
||||
resource.KindEncodingJSON: &CheckJSONCodec{},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// Kind returns a resource.Kind for this Schema with a JSON codec
|
||||
func CheckKind() resource.Kind {
|
||||
return kindCheck
|
||||
}
|
||||
|
||||
// Schema returns a resource.SimpleSchema representation of Check
|
||||
func CheckSchema() *resource.SimpleSchema {
|
||||
return schemaCheck
|
||||
}
|
||||
|
||||
// Interface compliance checks
|
||||
var _ resource.Schema = kindCheck
|
||||
14
apps/advisor/pkg/apis/advisor/v0alpha1/check_spec_gen.go
Normal file
14
apps/advisor/pkg/apis/advisor/v0alpha1/check_spec_gen.go
Normal file
@@ -0,0 +1,14 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
|
||||
package v0alpha1
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type CheckSpec struct {
|
||||
// Generic data input that a check can receive
|
||||
Data map[string]string `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
// NewCheckSpec creates a new CheckSpec object.
|
||||
func NewCheckSpec() *CheckSpec {
|
||||
return &CheckSpec{}
|
||||
}
|
||||
87
apps/advisor/pkg/apis/advisor/v0alpha1/check_status_gen.go
Normal file
87
apps/advisor/pkg/apis/advisor/v0alpha1/check_status_gen.go
Normal file
@@ -0,0 +1,87 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
|
||||
package v0alpha1
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type CheckReportFailure struct {
|
||||
// Severity of the failure
|
||||
Severity CheckReportFailureSeverity `json:"severity"`
|
||||
// Human readable reason for the failure
|
||||
Reason string `json:"reason"`
|
||||
// Action to take to resolve the failure
|
||||
Action string `json:"action"`
|
||||
// Step ID that the failure is associated with
|
||||
StepID string `json:"stepID"`
|
||||
// Item ID that the failure is associated with
|
||||
ItemID string `json:"itemID"`
|
||||
}
|
||||
|
||||
// NewCheckReportFailure creates a new CheckReportFailure object.
|
||||
func NewCheckReportFailure() *CheckReportFailure {
|
||||
return &CheckReportFailure{}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type CheckstatusOperatorState struct {
|
||||
// lastEvaluation is the ResourceVersion last evaluated
|
||||
LastEvaluation string `json:"lastEvaluation"`
|
||||
// state describes the state of the lastEvaluation.
|
||||
// It is limited to three possible states for machine evaluation.
|
||||
State CheckStatusOperatorStateState `json:"state"`
|
||||
// descriptiveState is an optional more descriptive state field which has no requirements on format
|
||||
DescriptiveState *string `json:"descriptiveState,omitempty"`
|
||||
// details contains any extra information that is operator-specific
|
||||
Details map[string]interface{} `json:"details,omitempty"`
|
||||
}
|
||||
|
||||
// NewCheckstatusOperatorState creates a new CheckstatusOperatorState object.
|
||||
func NewCheckstatusOperatorState() *CheckstatusOperatorState {
|
||||
return &CheckstatusOperatorState{}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type CheckStatus struct {
|
||||
Report CheckV0alpha1StatusReport `json:"report"`
|
||||
// operatorStates is a map of operator ID to operator state evaluations.
|
||||
// Any operator which consumes this kind SHOULD add its state evaluation information to this field.
|
||||
OperatorStates map[string]CheckstatusOperatorState `json:"operatorStates,omitempty"`
|
||||
// additionalFields is reserved for future use
|
||||
AdditionalFields map[string]interface{} `json:"additionalFields,omitempty"`
|
||||
}
|
||||
|
||||
// NewCheckStatus creates a new CheckStatus object.
|
||||
func NewCheckStatus() *CheckStatus {
|
||||
return &CheckStatus{
|
||||
Report: *NewCheckV0alpha1StatusReport(),
|
||||
}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type CheckReportFailureSeverity string
|
||||
|
||||
const (
|
||||
CheckReportFailureSeverityHigh CheckReportFailureSeverity = "high"
|
||||
CheckReportFailureSeverityLow CheckReportFailureSeverity = "low"
|
||||
)
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type CheckStatusOperatorStateState string
|
||||
|
||||
const (
|
||||
CheckStatusOperatorStateStateSuccess CheckStatusOperatorStateState = "success"
|
||||
CheckStatusOperatorStateStateInProgress CheckStatusOperatorStateState = "in_progress"
|
||||
CheckStatusOperatorStateStateFailed CheckStatusOperatorStateState = "failed"
|
||||
)
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type CheckV0alpha1StatusReport struct {
|
||||
// Number of elements analyzed
|
||||
Count int64 `json:"count"`
|
||||
// List of failures
|
||||
Failures []CheckReportFailure `json:"failures"`
|
||||
}
|
||||
|
||||
// NewCheckV0alpha1StatusReport creates a new CheckV0alpha1StatusReport object.
|
||||
func NewCheckV0alpha1StatusReport() *CheckV0alpha1StatusReport {
|
||||
return &CheckV0alpha1StatusReport{}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// Code generated by grafana-app-sdk. DO NOT EDIT.
|
||||
//
|
||||
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
|
||||
"github.com/grafana/grafana-app-sdk/resource"
|
||||
)
|
||||
|
||||
// CheckTypeJSONCodec is an implementation of resource.Codec for kubernetes JSON encoding
|
||||
type CheckTypeJSONCodec struct{}
|
||||
|
||||
// Read reads JSON-encoded bytes from `reader` and unmarshals them into `into`
|
||||
func (*CheckTypeJSONCodec) Read(reader io.Reader, into resource.Object) error {
|
||||
return json.NewDecoder(reader).Decode(into)
|
||||
}
|
||||
|
||||
// Write writes JSON-encoded bytes into `writer` marshaled from `from`
|
||||
func (*CheckTypeJSONCodec) Write(writer io.Writer, from resource.Object) error {
|
||||
return json.NewEncoder(writer).Encode(from)
|
||||
}
|
||||
|
||||
// Interface compliance checks
|
||||
var _ resource.Codec = &CheckTypeJSONCodec{}
|
||||
@@ -0,0 +1,28 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
time "time"
|
||||
)
|
||||
|
||||
// metadata contains embedded CommonMetadata and can be extended with custom string fields
|
||||
// TODO: use CommonMetadata instead of redefining here; currently needs to be defined here
|
||||
// without external reference as using the CommonMetadata reference breaks thema codegen.
|
||||
type CheckTypeMetadata struct {
|
||||
UpdateTimestamp time.Time `json:"updateTimestamp"`
|
||||
CreatedBy string `json:"createdBy"`
|
||||
Uid string `json:"uid"`
|
||||
CreationTimestamp time.Time `json:"creationTimestamp"`
|
||||
DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty"`
|
||||
Finalizers []string `json:"finalizers"`
|
||||
ResourceVersion string `json:"resourceVersion"`
|
||||
Generation int64 `json:"generation"`
|
||||
UpdatedBy string `json:"updatedBy"`
|
||||
Labels map[string]string `json:"labels"`
|
||||
}
|
||||
|
||||
// NewCheckTypeMetadata creates a new CheckTypeMetadata object.
|
||||
func NewCheckTypeMetadata() *CheckTypeMetadata {
|
||||
return &CheckTypeMetadata{}
|
||||
}
|
||||
266
apps/advisor/pkg/apis/advisor/v0alpha1/checktype_object_gen.go
Normal file
266
apps/advisor/pkg/apis/advisor/v0alpha1/checktype_object_gen.go
Normal file
@@ -0,0 +1,266 @@
|
||||
//
|
||||
// Code generated by grafana-app-sdk. DO NOT EDIT.
|
||||
//
|
||||
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/grafana/grafana-app-sdk/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"time"
|
||||
)
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type CheckType struct {
|
||||
metav1.TypeMeta `json:",inline" yaml:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata" yaml:"metadata"`
|
||||
Spec CheckTypeSpec `json:"spec" yaml:"spec"`
|
||||
CheckTypeStatus CheckTypeStatus `json:"status" yaml:"status"`
|
||||
}
|
||||
|
||||
func (o *CheckType) GetSpec() any {
|
||||
return o.Spec
|
||||
}
|
||||
|
||||
func (o *CheckType) SetSpec(spec any) error {
|
||||
cast, ok := spec.(CheckTypeSpec)
|
||||
if !ok {
|
||||
return fmt.Errorf("cannot set spec type %#v, not of type Spec", spec)
|
||||
}
|
||||
o.Spec = cast
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *CheckType) GetSubresources() map[string]any {
|
||||
return map[string]any{
|
||||
"status": o.CheckTypeStatus,
|
||||
}
|
||||
}
|
||||
|
||||
func (o *CheckType) GetSubresource(name string) (any, bool) {
|
||||
switch name {
|
||||
case "status":
|
||||
return o.CheckTypeStatus, true
|
||||
default:
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
|
||||
func (o *CheckType) SetSubresource(name string, value any) error {
|
||||
switch name {
|
||||
case "status":
|
||||
cast, ok := value.(CheckTypeStatus)
|
||||
if !ok {
|
||||
return fmt.Errorf("cannot set status type %#v, not of type CheckTypeStatus", value)
|
||||
}
|
||||
o.CheckTypeStatus = cast
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("subresource '%s' does not exist", name)
|
||||
}
|
||||
}
|
||||
|
||||
func (o *CheckType) GetStaticMetadata() resource.StaticMetadata {
|
||||
gvk := o.GroupVersionKind()
|
||||
return resource.StaticMetadata{
|
||||
Name: o.ObjectMeta.Name,
|
||||
Namespace: o.ObjectMeta.Namespace,
|
||||
Group: gvk.Group,
|
||||
Version: gvk.Version,
|
||||
Kind: gvk.Kind,
|
||||
}
|
||||
}
|
||||
|
||||
func (o *CheckType) SetStaticMetadata(metadata resource.StaticMetadata) {
|
||||
o.Name = metadata.Name
|
||||
o.Namespace = metadata.Namespace
|
||||
o.SetGroupVersionKind(schema.GroupVersionKind{
|
||||
Group: metadata.Group,
|
||||
Version: metadata.Version,
|
||||
Kind: metadata.Kind,
|
||||
})
|
||||
}
|
||||
|
||||
func (o *CheckType) GetCommonMetadata() resource.CommonMetadata {
|
||||
dt := o.DeletionTimestamp
|
||||
var deletionTimestamp *time.Time
|
||||
if dt != nil {
|
||||
deletionTimestamp = &dt.Time
|
||||
}
|
||||
// Legacy ExtraFields support
|
||||
extraFields := make(map[string]any)
|
||||
if o.Annotations != nil {
|
||||
extraFields["annotations"] = o.Annotations
|
||||
}
|
||||
if o.ManagedFields != nil {
|
||||
extraFields["managedFields"] = o.ManagedFields
|
||||
}
|
||||
if o.OwnerReferences != nil {
|
||||
extraFields["ownerReferences"] = o.OwnerReferences
|
||||
}
|
||||
return resource.CommonMetadata{
|
||||
UID: string(o.UID),
|
||||
ResourceVersion: o.ResourceVersion,
|
||||
Generation: o.Generation,
|
||||
Labels: o.Labels,
|
||||
CreationTimestamp: o.CreationTimestamp.Time,
|
||||
DeletionTimestamp: deletionTimestamp,
|
||||
Finalizers: o.Finalizers,
|
||||
UpdateTimestamp: o.GetUpdateTimestamp(),
|
||||
CreatedBy: o.GetCreatedBy(),
|
||||
UpdatedBy: o.GetUpdatedBy(),
|
||||
ExtraFields: extraFields,
|
||||
}
|
||||
}
|
||||
|
||||
func (o *CheckType) SetCommonMetadata(metadata resource.CommonMetadata) {
|
||||
o.UID = types.UID(metadata.UID)
|
||||
o.ResourceVersion = metadata.ResourceVersion
|
||||
o.Generation = metadata.Generation
|
||||
o.Labels = metadata.Labels
|
||||
o.CreationTimestamp = metav1.NewTime(metadata.CreationTimestamp)
|
||||
if metadata.DeletionTimestamp != nil {
|
||||
dt := metav1.NewTime(*metadata.DeletionTimestamp)
|
||||
o.DeletionTimestamp = &dt
|
||||
} else {
|
||||
o.DeletionTimestamp = nil
|
||||
}
|
||||
o.Finalizers = metadata.Finalizers
|
||||
if o.Annotations == nil {
|
||||
o.Annotations = make(map[string]string)
|
||||
}
|
||||
if !metadata.UpdateTimestamp.IsZero() {
|
||||
o.SetUpdateTimestamp(metadata.UpdateTimestamp)
|
||||
}
|
||||
if metadata.CreatedBy != "" {
|
||||
o.SetCreatedBy(metadata.CreatedBy)
|
||||
}
|
||||
if metadata.UpdatedBy != "" {
|
||||
o.SetUpdatedBy(metadata.UpdatedBy)
|
||||
}
|
||||
// Legacy support for setting Annotations, ManagedFields, and OwnerReferences via ExtraFields
|
||||
if metadata.ExtraFields != nil {
|
||||
if annotations, ok := metadata.ExtraFields["annotations"]; ok {
|
||||
if cast, ok := annotations.(map[string]string); ok {
|
||||
o.Annotations = cast
|
||||
}
|
||||
}
|
||||
if managedFields, ok := metadata.ExtraFields["managedFields"]; ok {
|
||||
if cast, ok := managedFields.([]metav1.ManagedFieldsEntry); ok {
|
||||
o.ManagedFields = cast
|
||||
}
|
||||
}
|
||||
if ownerReferences, ok := metadata.ExtraFields["ownerReferences"]; ok {
|
||||
if cast, ok := ownerReferences.([]metav1.OwnerReference); ok {
|
||||
o.OwnerReferences = cast
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (o *CheckType) GetCreatedBy() string {
|
||||
if o.ObjectMeta.Annotations == nil {
|
||||
o.ObjectMeta.Annotations = make(map[string]string)
|
||||
}
|
||||
|
||||
return o.ObjectMeta.Annotations["grafana.com/createdBy"]
|
||||
}
|
||||
|
||||
func (o *CheckType) SetCreatedBy(createdBy string) {
|
||||
if o.ObjectMeta.Annotations == nil {
|
||||
o.ObjectMeta.Annotations = make(map[string]string)
|
||||
}
|
||||
|
||||
o.ObjectMeta.Annotations["grafana.com/createdBy"] = createdBy
|
||||
}
|
||||
|
||||
func (o *CheckType) GetUpdateTimestamp() time.Time {
|
||||
if o.ObjectMeta.Annotations == nil {
|
||||
o.ObjectMeta.Annotations = make(map[string]string)
|
||||
}
|
||||
|
||||
parsed, _ := time.Parse(time.RFC3339, o.ObjectMeta.Annotations["grafana.com/updateTimestamp"])
|
||||
return parsed
|
||||
}
|
||||
|
||||
func (o *CheckType) SetUpdateTimestamp(updateTimestamp time.Time) {
|
||||
if o.ObjectMeta.Annotations == nil {
|
||||
o.ObjectMeta.Annotations = make(map[string]string)
|
||||
}
|
||||
|
||||
o.ObjectMeta.Annotations["grafana.com/updateTimestamp"] = updateTimestamp.Format(time.RFC3339)
|
||||
}
|
||||
|
||||
func (o *CheckType) GetUpdatedBy() string {
|
||||
if o.ObjectMeta.Annotations == nil {
|
||||
o.ObjectMeta.Annotations = make(map[string]string)
|
||||
}
|
||||
|
||||
return o.ObjectMeta.Annotations["grafana.com/updatedBy"]
|
||||
}
|
||||
|
||||
func (o *CheckType) SetUpdatedBy(updatedBy string) {
|
||||
if o.ObjectMeta.Annotations == nil {
|
||||
o.ObjectMeta.Annotations = make(map[string]string)
|
||||
}
|
||||
|
||||
o.ObjectMeta.Annotations["grafana.com/updatedBy"] = updatedBy
|
||||
}
|
||||
|
||||
func (o *CheckType) Copy() resource.Object {
|
||||
return resource.CopyObject(o)
|
||||
}
|
||||
|
||||
func (o *CheckType) DeepCopyObject() runtime.Object {
|
||||
return o.Copy()
|
||||
}
|
||||
|
||||
// Interface compliance compile-time check
|
||||
var _ resource.Object = &CheckType{}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type CheckTypeList struct {
|
||||
metav1.TypeMeta `json:",inline" yaml:",inline"`
|
||||
metav1.ListMeta `json:"metadata" yaml:"metadata"`
|
||||
Items []CheckType `json:"items" yaml:"items"`
|
||||
}
|
||||
|
||||
func (o *CheckTypeList) DeepCopyObject() runtime.Object {
|
||||
return o.Copy()
|
||||
}
|
||||
|
||||
func (o *CheckTypeList) Copy() resource.ListObject {
|
||||
cpy := &CheckTypeList{
|
||||
TypeMeta: o.TypeMeta,
|
||||
Items: make([]CheckType, len(o.Items)),
|
||||
}
|
||||
o.ListMeta.DeepCopyInto(&cpy.ListMeta)
|
||||
for i := 0; i < len(o.Items); i++ {
|
||||
if item, ok := o.Items[i].Copy().(*CheckType); ok {
|
||||
cpy.Items[i] = *item
|
||||
}
|
||||
}
|
||||
return cpy
|
||||
}
|
||||
|
||||
func (o *CheckTypeList) GetItems() []resource.Object {
|
||||
items := make([]resource.Object, len(o.Items))
|
||||
for i := 0; i < len(o.Items); i++ {
|
||||
items[i] = &o.Items[i]
|
||||
}
|
||||
return items
|
||||
}
|
||||
|
||||
func (o *CheckTypeList) SetItems(items []resource.Object) {
|
||||
o.Items = make([]CheckType, len(items))
|
||||
for i := 0; i < len(items); i++ {
|
||||
o.Items[i] = *items[i].(*CheckType)
|
||||
}
|
||||
}
|
||||
|
||||
// Interface compliance compile-time check
|
||||
var _ resource.ListObject = &CheckTypeList{}
|
||||
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// Code generated by grafana-app-sdk. DO NOT EDIT.
|
||||
//
|
||||
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
"github.com/grafana/grafana-app-sdk/resource"
|
||||
)
|
||||
|
||||
// schema is unexported to prevent accidental overwrites
|
||||
var (
|
||||
schemaCheckType = resource.NewSimpleSchema("advisor.grafana.app", "v0alpha1", &CheckType{}, &CheckTypeList{}, resource.WithKind("CheckType"),
|
||||
resource.WithPlural("checktypes"), resource.WithScope(resource.NamespacedScope))
|
||||
kindCheckType = resource.Kind{
|
||||
Schema: schemaCheckType,
|
||||
Codecs: map[resource.KindEncoding]resource.Codec{
|
||||
resource.KindEncodingJSON: &CheckTypeJSONCodec{},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// Kind returns a resource.Kind for this Schema with a JSON codec
|
||||
func CheckTypeKind() resource.Kind {
|
||||
return kindCheckType
|
||||
}
|
||||
|
||||
// Schema returns a resource.SimpleSchema representation of CheckType
|
||||
func CheckTypeSchema() *resource.SimpleSchema {
|
||||
return schemaCheckType
|
||||
}
|
||||
|
||||
// Interface compliance checks
|
||||
var _ resource.Schema = kindCheckType
|
||||
26
apps/advisor/pkg/apis/advisor/v0alpha1/checktype_spec_gen.go
Normal file
26
apps/advisor/pkg/apis/advisor/v0alpha1/checktype_spec_gen.go
Normal file
@@ -0,0 +1,26 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
|
||||
package v0alpha1
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type CheckTypeStep struct {
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
StepID string `json:"stepID"`
|
||||
}
|
||||
|
||||
// NewCheckTypeStep creates a new CheckTypeStep object.
|
||||
func NewCheckTypeStep() *CheckTypeStep {
|
||||
return &CheckTypeStep{}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type CheckTypeSpec struct {
|
||||
Name string `json:"name"`
|
||||
Steps []CheckTypeStep `json:"steps"`
|
||||
}
|
||||
|
||||
// NewCheckTypeSpec creates a new CheckTypeSpec object.
|
||||
func NewCheckTypeSpec() *CheckTypeSpec {
|
||||
return &CheckTypeSpec{}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
|
||||
package v0alpha1
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type CheckTypestatusOperatorState struct {
|
||||
// lastEvaluation is the ResourceVersion last evaluated
|
||||
LastEvaluation string `json:"lastEvaluation"`
|
||||
// state describes the state of the lastEvaluation.
|
||||
// It is limited to three possible states for machine evaluation.
|
||||
State CheckTypeStatusOperatorStateState `json:"state"`
|
||||
// descriptiveState is an optional more descriptive state field which has no requirements on format
|
||||
DescriptiveState *string `json:"descriptiveState,omitempty"`
|
||||
// details contains any extra information that is operator-specific
|
||||
Details map[string]interface{} `json:"details,omitempty"`
|
||||
}
|
||||
|
||||
// NewCheckTypestatusOperatorState creates a new CheckTypestatusOperatorState object.
|
||||
func NewCheckTypestatusOperatorState() *CheckTypestatusOperatorState {
|
||||
return &CheckTypestatusOperatorState{}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type CheckTypeStatus struct {
|
||||
// operatorStates is a map of operator ID to operator state evaluations.
|
||||
// Any operator which consumes this kind SHOULD add its state evaluation information to this field.
|
||||
OperatorStates map[string]CheckTypestatusOperatorState `json:"operatorStates,omitempty"`
|
||||
// additionalFields is reserved for future use
|
||||
AdditionalFields map[string]interface{} `json:"additionalFields,omitempty"`
|
||||
}
|
||||
|
||||
// NewCheckTypeStatus creates a new CheckTypeStatus object.
|
||||
func NewCheckTypeStatus() *CheckTypeStatus {
|
||||
return &CheckTypeStatus{}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type CheckTypeStatusOperatorStateState string
|
||||
|
||||
const (
|
||||
CheckTypeStatusOperatorStateStateSuccess CheckTypeStatusOperatorStateState = "success"
|
||||
CheckTypeStatusOperatorStateStateInProgress CheckTypeStatusOperatorStateState = "in_progress"
|
||||
CheckTypeStatusOperatorStateStateFailed CheckTypeStatusOperatorStateState = "failed"
|
||||
)
|
||||
18
apps/advisor/pkg/apis/advisor/v0alpha1/constants.go
Normal file
18
apps/advisor/pkg/apis/advisor/v0alpha1/constants.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package v0alpha1
|
||||
|
||||
import "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
const (
|
||||
// Group is the API group used by all kinds in this package
|
||||
Group = "advisor.grafana.app"
|
||||
// Version is the API version used by all kinds in this package
|
||||
Version = "v0alpha1"
|
||||
)
|
||||
|
||||
var (
|
||||
// GroupVersion is a schema.GroupVersion consisting of the Group and Version constants for this package
|
||||
GroupVersion = schema.GroupVersion{
|
||||
Group: Group,
|
||||
Version: Version,
|
||||
}
|
||||
)
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
// Code generated by grafana-app-sdk. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
common "k8s.io/kube-openapi/pkg/common"
|
||||
@@ -12,22 +12,23 @@ import (
|
||||
|
||||
func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition {
|
||||
return map[string]common.OpenAPIDefinition{
|
||||
"github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.Investigation": schema_pkg_apis_investigation_v1alpha1_Investigation(ref),
|
||||
"github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationAbsoluteTimeRange": schema_pkg_apis_investigation_v1alpha1_InvestigationAbsoluteTimeRange(ref),
|
||||
"github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationComment": schema_pkg_apis_investigation_v1alpha1_InvestigationComment(ref),
|
||||
"github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationDataQueryLogs": schema_pkg_apis_investigation_v1alpha1_InvestigationDataQueryLogs(ref),
|
||||
"github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationDataQueryMetrics": schema_pkg_apis_investigation_v1alpha1_InvestigationDataQueryMetrics(ref),
|
||||
"github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationDatasourceRef": schema_pkg_apis_investigation_v1alpha1_InvestigationDatasourceRef(ref),
|
||||
"github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationInvestigationItem": schema_pkg_apis_investigation_v1alpha1_InvestigationInvestigationItem(ref),
|
||||
"github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationList": schema_pkg_apis_investigation_v1alpha1_InvestigationList(ref),
|
||||
"github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationOperatorState": schema_pkg_apis_investigation_v1alpha1_InvestigationOperatorState(ref),
|
||||
"github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationSpec": schema_pkg_apis_investigation_v1alpha1_InvestigationSpec(ref),
|
||||
"github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationStatus": schema_pkg_apis_investigation_v1alpha1_InvestigationStatus(ref),
|
||||
"github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationstatusOperatorState": schema_pkg_apis_investigation_v1alpha1_InvestigationstatusOperatorState(ref),
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.Check": schema_pkg_apis_advisor_v0alpha1_Check(ref),
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckList": schema_pkg_apis_advisor_v0alpha1_CheckList(ref),
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckReportFailure": schema_pkg_apis_advisor_v0alpha1_CheckReportFailure(ref),
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckSpec": schema_pkg_apis_advisor_v0alpha1_CheckSpec(ref),
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckStatus": schema_pkg_apis_advisor_v0alpha1_CheckStatus(ref),
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckType": schema_pkg_apis_advisor_v0alpha1_CheckType(ref),
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckTypeList": schema_pkg_apis_advisor_v0alpha1_CheckTypeList(ref),
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckTypeSpec": schema_pkg_apis_advisor_v0alpha1_CheckTypeSpec(ref),
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckTypeStatus": schema_pkg_apis_advisor_v0alpha1_CheckTypeStatus(ref),
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckTypeStep": schema_pkg_apis_advisor_v0alpha1_CheckTypeStep(ref),
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckTypestatusOperatorState": schema_pkg_apis_advisor_v0alpha1_CheckTypestatusOperatorState(ref),
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckV0alpha1StatusReport": schema_pkg_apis_advisor_v0alpha1_CheckV0alpha1StatusReport(ref),
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckstatusOperatorState": schema_pkg_apis_advisor_v0alpha1_CheckstatusOperatorState(ref),
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_investigation_v1alpha1_Investigation(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
func schema_pkg_apis_advisor_v0alpha1_Check(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
@@ -56,13 +57,13 @@ func schema_pkg_apis_investigation_v1alpha1_Investigation(ref common.ReferenceCa
|
||||
"spec": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationSpec"),
|
||||
Ref: ref("github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckSpec"),
|
||||
},
|
||||
},
|
||||
"status": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationStatus"),
|
||||
Ref: ref("github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckStatus"),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -70,289 +71,11 @@ func schema_pkg_apis_investigation_v1alpha1_Investigation(ref common.ReferenceCa
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationSpec", "github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckSpec", "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_investigation_v1alpha1_InvestigationAbsoluteTimeRange(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "AbsoluteTimeRange is a time range specified by absolute timestamps.",
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"from": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: 0,
|
||||
Type: []string{"number"},
|
||||
Format: "float",
|
||||
},
|
||||
},
|
||||
"to": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: 0,
|
||||
Type: []string{"number"},
|
||||
Format: "float",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"from", "to"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_investigation_v1alpha1_InvestigationComment(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Comment is a comment on an investigation item.",
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"authorUserID": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"bodyMarkdown": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"authorUserID", "bodyMarkdown"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_investigation_v1alpha1_InvestigationDataQueryLogs(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "DataQueryLogs is a data query for logs.",
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"datasource": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "DatasourceRef is a reference to a datasource.",
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationDatasourceRef"),
|
||||
},
|
||||
},
|
||||
"expr": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "expr is the expression of the query.",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"maxLines": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "maxLines (optional) is used to limit the number of log rows returned.",
|
||||
Type: []string{"integer"},
|
||||
Format: "int64",
|
||||
},
|
||||
},
|
||||
"refId": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "refId is the reference ID of the query.",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"datasource", "expr", "refId"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationDatasourceRef"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_investigation_v1alpha1_InvestigationDataQueryMetrics(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "DataQueryMetrics is a data query for metrics.",
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"datasource": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "DatasourceRef is a reference to a datasource.",
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationDatasourceRef"),
|
||||
},
|
||||
},
|
||||
"expr": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"refId": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"datasource", "expr", "refId"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationDatasourceRef"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_investigation_v1alpha1_InvestigationDatasourceRef(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "DatasourceRef is a reference to a datasource.",
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"apiVersion": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"name": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"type": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"uid": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"apiVersion", "name", "type", "uid"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_investigation_v1alpha1_InvestigationInvestigationItem(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "InvestigationItem is an item in an investigation.",
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"dataQuery": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "dataQuery contains the query used to generate this item.",
|
||||
Type: []string{"object"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"iconPath": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "iconPath (optional) is the path to the icon for the item.",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"id": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"note": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "note (optional) is a comment on the item.",
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationComment"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"origin": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "origin is where the item was created from.",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"queryType": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "queryType is the type of the query used to generate this item.",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"timeRange": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "AbsoluteTimeRange is a time range specified by absolute timestamps.",
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationAbsoluteTimeRange"),
|
||||
},
|
||||
},
|
||||
"title": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"type": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "type is the type of the item \"timeseries\", \"heatmap\", \"log-table\" (not an enum to allow for future extensions).",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"url": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "url is the URL to the item.",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"dataQuery", "id", "origin", "queryType", "timeRange", "title", "type", "url"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationAbsoluteTimeRange", "github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationComment"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_investigation_v1alpha1_InvestigationList(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
func schema_pkg_apis_advisor_v0alpha1_CheckList(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
@@ -385,7 +108,7 @@ func schema_pkg_apis_investigation_v1alpha1_InvestigationList(ref common.Referen
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.Investigation"),
|
||||
Ref: ref("github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.Check"),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -396,112 +119,118 @@ func schema_pkg_apis_investigation_v1alpha1_InvestigationList(ref common.Referen
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.Investigation", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"},
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.Check", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_investigation_v1alpha1_InvestigationOperatorState(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
func schema_pkg_apis_advisor_v0alpha1_CheckReportFailure(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "InvestigationOperatorState defines model for InvestigationOperatorState.",
|
||||
Type: []string{"object"},
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"descriptiveState": {
|
||||
"severity": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "descriptiveState is an optional more descriptive state field which has no requirements on format",
|
||||
Description: "Severity of the failure",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"details": {
|
||||
"reason": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "details contains any extra information that is operator-specific",
|
||||
Description: "Human readable reason for the failure",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"action": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Action to take to resolve the failure",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"stepID": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Step ID that the failure is associated with",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"itemID": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Item ID that the failure is associated with",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"severity", "reason", "action", "stepID", "itemID"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_advisor_v0alpha1_CheckSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"data": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Generic data input that a check can receive",
|
||||
Type: []string{"object"},
|
||||
AdditionalProperties: &spec.SchemaOrBool{
|
||||
Allows: true,
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Format: "",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"lastEvaluation": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "lastEvaluation is the ResourceVersion last evaluated",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"state": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "state describes the state of the lastEvaluation. It is limited to three possible states for machine evaluation.",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"lastEvaluation", "state"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_investigation_v1alpha1_InvestigationSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
func schema_pkg_apis_advisor_v0alpha1_CheckStatus(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "InvestigationSpec defines model for InvestigationSpec.",
|
||||
Type: []string{"object"},
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"items": {
|
||||
"report": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckV0alpha1StatusReport"),
|
||||
},
|
||||
},
|
||||
"operatorStates": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "operatorStates is a map of operator ID to operator state evaluations. Any operator which consumes this kind SHOULD add its state evaluation information to this field.",
|
||||
Type: []string{"object"},
|
||||
AdditionalProperties: &spec.SchemaOrBool{
|
||||
Allows: true,
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationInvestigationItem"),
|
||||
Ref: ref("github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckstatusOperatorState"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"status": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"title": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"items", "status", "title"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationInvestigationItem"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_investigation_v1alpha1_InvestigationStatus(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "InvestigationStatus defines model for InvestigationStatus.",
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"additionalFields": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "additionalFields is reserved for future use",
|
||||
@@ -517,6 +246,151 @@ func schema_pkg_apis_investigation_v1alpha1_InvestigationStatus(ref common.Refer
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"report"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckV0alpha1StatusReport", "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckstatusOperatorState"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_advisor_v0alpha1_CheckType(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"kind": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"apiVersion": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"metadata": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"),
|
||||
},
|
||||
},
|
||||
"spec": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckTypeSpec"),
|
||||
},
|
||||
},
|
||||
"status": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckTypeStatus"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"metadata", "spec", "status"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckTypeSpec", "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckTypeStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_advisor_v0alpha1_CheckTypeList(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"kind": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"apiVersion": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"metadata": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"),
|
||||
},
|
||||
},
|
||||
"items": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckType"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"metadata", "items"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckType", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_advisor_v0alpha1_CheckTypeSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"name": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"steps": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckTypeStep"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"name", "steps"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckTypeStep"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_advisor_v0alpha1_CheckTypeStatus(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"operatorStates": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "operatorStates is a map of operator ID to operator state evaluations. Any operator which consumes this kind SHOULD add its state evaluation information to this field.",
|
||||
@@ -526,7 +400,22 @@ func schema_pkg_apis_investigation_v1alpha1_InvestigationStatus(ref common.Refer
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationstatusOperatorState"),
|
||||
Ref: ref("github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckTypestatusOperatorState"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"additionalFields": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "additionalFields is reserved for future use",
|
||||
Type: []string{"object"},
|
||||
AdditionalProperties: &spec.SchemaOrBool{
|
||||
Allows: true,
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -536,17 +425,66 @@ func schema_pkg_apis_investigation_v1alpha1_InvestigationStatus(ref common.Refer
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationstatusOperatorState"},
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckTypestatusOperatorState"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_investigation_v1alpha1_InvestigationstatusOperatorState(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
func schema_pkg_apis_advisor_v0alpha1_CheckTypeStep(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "InvestigationstatusOperatorState defines model for Investigationstatus.#OperatorState.",
|
||||
Type: []string{"object"},
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"title": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"description": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"stepID": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"title", "description", "stepID"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_advisor_v0alpha1_CheckTypestatusOperatorState(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"lastEvaluation": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "lastEvaluation is the ResourceVersion last evaluated",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"state": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "state describes the state of the lastEvaluation. It is limited to three possible states for machine evaluation.",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"descriptiveState": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "descriptiveState is an optional more descriptive state field which has no requirements on format",
|
||||
@@ -569,6 +507,56 @@ func schema_pkg_apis_investigation_v1alpha1_InvestigationstatusOperatorState(ref
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"lastEvaluation", "state"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_advisor_v0alpha1_CheckV0alpha1StatusReport(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"count": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Number of elements analyzed",
|
||||
Default: 0,
|
||||
Type: []string{"integer"},
|
||||
Format: "int64",
|
||||
},
|
||||
},
|
||||
"failures": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "List of failures",
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckReportFailure"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"count", "failures"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckReportFailure"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_advisor_v0alpha1_CheckstatusOperatorState(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"lastEvaluation": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "lastEvaluation is the ResourceVersion last evaluated",
|
||||
@@ -585,6 +573,28 @@ func schema_pkg_apis_investigation_v1alpha1_InvestigationstatusOperatorState(ref
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"descriptiveState": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "descriptiveState is an optional more descriptive state field which has no requirements on format",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"details": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "details contains any extra information that is operator-specific",
|
||||
Type: []string{"object"},
|
||||
AdditionalProperties: &spec.SchemaOrBool{
|
||||
Allows: true,
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"lastEvaluation", "state"},
|
||||
},
|
||||
73
apps/advisor/pkg/apis/advisor_manifest.go
Normal file
73
apps/advisor/pkg/apis/advisor_manifest.go
Normal file
@@ -0,0 +1,73 @@
|
||||
//
|
||||
// This file is generated by grafana-app-sdk
|
||||
// DO NOT EDIT
|
||||
//
|
||||
|
||||
package apis
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/grafana/grafana-app-sdk/app"
|
||||
)
|
||||
|
||||
var (
|
||||
rawSchemaCheckv0alpha1 = []byte(`{"spec":{"properties":{"data":{"additionalProperties":{"type":"string"},"description":"Generic data input that a check can receive","type":"object"}},"type":"object"},"status":{"properties":{"additionalFields":{"description":"additionalFields is reserved for future use","type":"object","x-kubernetes-preserve-unknown-fields":true},"operatorStates":{"additionalProperties":{"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"description":"details contains any extra information that is operator-specific","type":"object","x-kubernetes-preserve-unknown-fields":true},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"},"report":{"properties":{"count":{"description":"Number of elements analyzed","type":"integer"},"failures":{"description":"List of failures","items":{"properties":{"action":{"description":"Action to take to resolve the failure","type":"string"},"itemID":{"description":"Item ID that the failure is associated with","type":"string"},"reason":{"description":"Human readable reason for the failure","type":"string"},"severity":{"description":"Severity of the failure","enum":["high","low"],"type":"string"},"stepID":{"description":"Step ID that the failure is associated with","type":"string"}},"required":["severity","reason","action","stepID","itemID"],"type":"object"},"type":"array"}},"required":["count","failures"],"type":"object"}},"required":["report"],"type":"object","x-kubernetes-preserve-unknown-fields":true}}`)
|
||||
versionSchemaCheckv0alpha1 app.VersionSchema
|
||||
_ = json.Unmarshal(rawSchemaCheckv0alpha1, &versionSchemaCheckv0alpha1)
|
||||
rawSchemaCheckTypev0alpha1 = []byte(`{"spec":{"properties":{"name":{"type":"string"},"steps":{"items":{"properties":{"description":{"type":"string"},"stepID":{"type":"string"},"title":{"type":"string"}},"required":["title","description","stepID"],"type":"object"},"type":"array"}},"required":["name","steps"],"type":"object"},"status":{"properties":{"additionalFields":{"description":"additionalFields is reserved for future use","type":"object","x-kubernetes-preserve-unknown-fields":true},"operatorStates":{"additionalProperties":{"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"description":"details contains any extra information that is operator-specific","type":"object","x-kubernetes-preserve-unknown-fields":true},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"}},"type":"object","x-kubernetes-preserve-unknown-fields":true}}`)
|
||||
versionSchemaCheckTypev0alpha1 app.VersionSchema
|
||||
_ = json.Unmarshal(rawSchemaCheckTypev0alpha1, &versionSchemaCheckTypev0alpha1)
|
||||
)
|
||||
|
||||
var appManifestData = app.ManifestData{
|
||||
AppName: "advisor",
|
||||
Group: "advisor.grafana.app",
|
||||
Kinds: []app.ManifestKind{
|
||||
{
|
||||
Kind: "Check",
|
||||
Scope: "Namespaced",
|
||||
Conversion: false,
|
||||
Versions: []app.ManifestKindVersion{
|
||||
{
|
||||
Name: "v0alpha1",
|
||||
Admission: &app.AdmissionCapabilities{
|
||||
Validation: &app.ValidationCapability{
|
||||
Operations: []app.AdmissionOperation{
|
||||
app.AdmissionOperationCreate,
|
||||
app.AdmissionOperationUpdate,
|
||||
},
|
||||
},
|
||||
},
|
||||
Schema: &versionSchemaCheckv0alpha1,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
Kind: "CheckType",
|
||||
Scope: "Namespaced",
|
||||
Conversion: false,
|
||||
Versions: []app.ManifestKindVersion{
|
||||
{
|
||||
Name: "v0alpha1",
|
||||
Schema: &versionSchemaCheckTypev0alpha1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func jsonToMap(j string) map[string]any {
|
||||
m := make(map[string]any)
|
||||
json.Unmarshal([]byte(j), &j)
|
||||
return m
|
||||
}
|
||||
|
||||
func LocalManifest() app.Manifest {
|
||||
return app.NewEmbeddedManifest(appManifestData)
|
||||
}
|
||||
|
||||
func RemoteManifest() app.Manifest {
|
||||
return app.NewAPIServerManifest("advisor")
|
||||
}
|
||||
116
apps/advisor/pkg/app/app.go
Normal file
116
apps/advisor/pkg/app/app.go
Normal file
@@ -0,0 +1,116 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/grafana/grafana-app-sdk/app"
|
||||
"github.com/grafana/grafana-app-sdk/k8s"
|
||||
"github.com/grafana/grafana-app-sdk/resource"
|
||||
"github.com/grafana/grafana-app-sdk/simple"
|
||||
advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/app/checkregistry"
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/app/checks"
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/app/checkscheduler"
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/app/checktyperegisterer"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
func New(cfg app.Config) (app.App, error) {
|
||||
// Read config
|
||||
specificConfig, ok := cfg.SpecificConfig.(checkregistry.AdvisorAppConfig)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid config type")
|
||||
}
|
||||
checkRegistry := specificConfig.CheckRegistry
|
||||
|
||||
// Prepare storage client
|
||||
clientGenerator := k8s.NewClientRegistry(cfg.KubeConfig, k8s.ClientConfig{})
|
||||
client, err := clientGenerator.ClientFor(advisorv0alpha1.CheckKind())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Initialize checks
|
||||
checkMap := map[string]checks.Check{}
|
||||
for _, c := range checkRegistry.Checks() {
|
||||
checkMap[c.ID()] = c
|
||||
}
|
||||
|
||||
simpleConfig := simple.AppConfig{
|
||||
Name: "advisor",
|
||||
KubeConfig: cfg.KubeConfig,
|
||||
InformerConfig: simple.AppInformerConfig{
|
||||
ErrorHandler: func(ctx context.Context, err error) {
|
||||
klog.ErrorS(err, "Informer processing error")
|
||||
},
|
||||
},
|
||||
ManagedKinds: []simple.AppManagedKind{
|
||||
{
|
||||
Kind: advisorv0alpha1.CheckKind(),
|
||||
Validator: &simple.Validator{
|
||||
ValidateFunc: func(ctx context.Context, req *app.AdmissionRequest) error {
|
||||
if req.Object != nil {
|
||||
_, err := getCheck(req.Object, checkMap)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
},
|
||||
Watcher: &simple.Watcher{
|
||||
AddFunc: func(ctx context.Context, obj resource.Object) error {
|
||||
check, err := getCheck(obj, checkMap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return processCheck(ctx, client, obj, check)
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Kind: advisorv0alpha1.CheckTypeKind(),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
a, err := simple.NewApp(simpleConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = a.ValidateManifest(cfg.ManifestData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Save check types as resources
|
||||
ctr, err := checktyperegisterer.New(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
a.AddRunnable(ctr)
|
||||
|
||||
// Start scheduler
|
||||
csch, err := checkscheduler.New(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
a.AddRunnable(csch)
|
||||
|
||||
return a, nil
|
||||
}
|
||||
|
||||
func GetKinds() map[schema.GroupVersion][]resource.Kind {
|
||||
gv := schema.GroupVersion{
|
||||
// Group and version are the same for all checks
|
||||
Group: advisorv0alpha1.CheckKind().Group(),
|
||||
Version: advisorv0alpha1.CheckKind().Version(),
|
||||
}
|
||||
return map[schema.GroupVersion][]resource.Kind{
|
||||
gv: {
|
||||
advisorv0alpha1.CheckKind(),
|
||||
advisorv0alpha1.CheckTypeKind(),
|
||||
},
|
||||
}
|
||||
}
|
||||
31
apps/advisor/pkg/app/authorizer.go
Normal file
31
apps/advisor/pkg/app/authorizer.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
)
|
||||
|
||||
func GetAuthorizer() authorizer.Authorizer {
|
||||
return authorizer.AuthorizerFunc(func(
|
||||
ctx context.Context, attr authorizer.Attributes,
|
||||
) (authorized authorizer.Decision, reason string, err error) {
|
||||
if !attr.IsResourceRequest() {
|
||||
return authorizer.DecisionNoOpinion, "", nil
|
||||
}
|
||||
|
||||
// require a user
|
||||
u, err := identity.GetRequester(ctx)
|
||||
if err != nil {
|
||||
return authorizer.DecisionDeny, "valid user is required", err
|
||||
}
|
||||
|
||||
// check if is admin
|
||||
if u.GetIsGrafanaAdmin() {
|
||||
return authorizer.DecisionAllow, "", nil
|
||||
}
|
||||
|
||||
return authorizer.DecisionDeny, "forbidden", nil
|
||||
})
|
||||
}
|
||||
78
apps/advisor/pkg/app/authorizer_test.go
Normal file
78
apps/advisor/pkg/app/authorizer_test.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
)
|
||||
|
||||
func TestGetAuthorizer(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
ctx context.Context
|
||||
attr authorizer.Attributes
|
||||
expectedDecision authorizer.Decision
|
||||
expectedReason string
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
name: "non-resource request",
|
||||
ctx: context.TODO(),
|
||||
attr: &mockAttributes{resourceRequest: false},
|
||||
expectedDecision: authorizer.DecisionNoOpinion,
|
||||
expectedReason: "",
|
||||
expectedErr: nil,
|
||||
},
|
||||
{
|
||||
name: "user is admin",
|
||||
ctx: identity.WithRequester(context.TODO(), &mockUser{isGrafanaAdmin: true}),
|
||||
attr: &mockAttributes{resourceRequest: true},
|
||||
expectedDecision: authorizer.DecisionAllow,
|
||||
expectedReason: "",
|
||||
expectedErr: nil,
|
||||
},
|
||||
{
|
||||
name: "user is not admin",
|
||||
ctx: identity.WithRequester(context.TODO(), &mockUser{isGrafanaAdmin: false}),
|
||||
attr: &mockAttributes{resourceRequest: true},
|
||||
expectedDecision: authorizer.DecisionDeny,
|
||||
expectedReason: "forbidden",
|
||||
expectedErr: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
auth := GetAuthorizer()
|
||||
decision, reason, err := auth.Authorize(tt.ctx, tt.attr)
|
||||
assert.Equal(t, tt.expectedDecision, decision)
|
||||
assert.Equal(t, tt.expectedReason, reason)
|
||||
assert.Equal(t, tt.expectedErr, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type mockAttributes struct {
|
||||
authorizer.Attributes
|
||||
resourceRequest bool
|
||||
}
|
||||
|
||||
func (m *mockAttributes) IsResourceRequest() bool {
|
||||
return m.resourceRequest
|
||||
}
|
||||
|
||||
// Implement other methods of authorizer.Attributes as needed
|
||||
|
||||
type mockUser struct {
|
||||
identity.Requester
|
||||
isGrafanaAdmin bool
|
||||
}
|
||||
|
||||
func (m *mockUser) GetIsGrafanaAdmin() bool {
|
||||
return m.isGrafanaAdmin
|
||||
}
|
||||
|
||||
// Implement other methods of identity.Requester as needed
|
||||
65
apps/advisor/pkg/app/checkregistry/checkregistry.go
Normal file
65
apps/advisor/pkg/app/checkregistry/checkregistry.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package checkregistry
|
||||
|
||||
import (
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/app/checks"
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/app/checks/datasourcecheck"
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/app/checks/plugincheck"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/plugins/repo"
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/managedplugins"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/plugincontext"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/plugininstaller"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
||||
)
|
||||
|
||||
type CheckService interface {
|
||||
Checks() []checks.Check
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
datasourceSvc datasources.DataSourceService
|
||||
pluginStore pluginstore.Store
|
||||
pluginContextProvider *plugincontext.Provider
|
||||
pluginClient plugins.Client
|
||||
pluginRepo repo.Service
|
||||
pluginPreinstall plugininstaller.Preinstall
|
||||
managedPlugins managedplugins.Manager
|
||||
}
|
||||
|
||||
func ProvideService(datasourceSvc datasources.DataSourceService, pluginStore pluginstore.Store,
|
||||
pluginContextProvider *plugincontext.Provider, pluginClient plugins.Client,
|
||||
pluginRepo repo.Service, pluginPreinstall plugininstaller.Preinstall, managedPlugins managedplugins.Manager) *Service {
|
||||
return &Service{
|
||||
datasourceSvc: datasourceSvc,
|
||||
pluginStore: pluginStore,
|
||||
pluginContextProvider: pluginContextProvider,
|
||||
pluginClient: pluginClient,
|
||||
pluginRepo: pluginRepo,
|
||||
pluginPreinstall: pluginPreinstall,
|
||||
managedPlugins: managedPlugins,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) Checks() []checks.Check {
|
||||
return []checks.Check{
|
||||
datasourcecheck.New(
|
||||
s.datasourceSvc,
|
||||
s.pluginStore,
|
||||
s.pluginContextProvider,
|
||||
s.pluginClient,
|
||||
),
|
||||
plugincheck.New(
|
||||
s.pluginStore,
|
||||
s.pluginRepo,
|
||||
s.pluginPreinstall,
|
||||
s.managedPlugins,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// AdvisorAppConfig is the configuration received from Grafana to run the app
|
||||
type AdvisorAppConfig struct {
|
||||
CheckRegistry CheckService
|
||||
PluginConfig map[string]string
|
||||
}
|
||||
150
apps/advisor/pkg/app/checks/datasourcecheck/check.go
Normal file
150
apps/advisor/pkg/app/checks/datasourcecheck/check.go
Normal file
@@ -0,0 +1,150 @@
|
||||
package datasourcecheck
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
advisor "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/app/checks"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
|
||||
type check struct {
|
||||
DatasourceSvc datasources.DataSourceService
|
||||
PluginStore pluginstore.Store
|
||||
PluginContextProvider pluginContextProvider
|
||||
PluginClient plugins.Client
|
||||
}
|
||||
|
||||
func New(
|
||||
datasourceSvc datasources.DataSourceService,
|
||||
pluginStore pluginstore.Store,
|
||||
pluginContextProvider pluginContextProvider,
|
||||
pluginClient plugins.Client,
|
||||
) checks.Check {
|
||||
return &check{
|
||||
DatasourceSvc: datasourceSvc,
|
||||
PluginStore: pluginStore,
|
||||
PluginContextProvider: pluginContextProvider,
|
||||
PluginClient: pluginClient,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *check) Items(ctx context.Context) ([]any, error) {
|
||||
dss, err := c.DatasourceSvc.GetAllDataSources(ctx, &datasources.GetAllDataSourcesQuery{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := make([]any, len(dss))
|
||||
for i, ds := range dss {
|
||||
res[i] = ds
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (c *check) ID() string {
|
||||
return "datasource"
|
||||
}
|
||||
|
||||
func (c *check) Steps() []checks.Step {
|
||||
return []checks.Step{
|
||||
&uidValidationStep{},
|
||||
&healthCheckStep{
|
||||
PluginContextProvider: c.PluginContextProvider,
|
||||
PluginClient: c.PluginClient,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type uidValidationStep struct{}
|
||||
|
||||
func (s *uidValidationStep) ID() string {
|
||||
return "uid-validation"
|
||||
}
|
||||
|
||||
func (s *uidValidationStep) Title() string {
|
||||
return "UID validation"
|
||||
}
|
||||
|
||||
func (s *uidValidationStep) Description() string {
|
||||
return "Check if the UID of each data source is valid."
|
||||
}
|
||||
|
||||
func (s *uidValidationStep) Run(ctx context.Context, obj *advisor.CheckSpec, i any) (*advisor.CheckReportFailure, error) {
|
||||
ds, ok := i.(*datasources.DataSource)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid item type %T", i)
|
||||
}
|
||||
// Data source UID validation
|
||||
err := util.ValidateUID(ds.UID)
|
||||
if err != nil {
|
||||
return checks.NewCheckReportFailure(
|
||||
advisor.CheckReportFailureSeverityLow,
|
||||
fmt.Sprintf("Invalid UID '%s' for data source %s", ds.UID, ds.Name),
|
||||
"Check the <a href='https://grafana.com/docs/grafana/latest/upgrade-guide/upgrade-v11.2/#grafana-data-source-uid-format-enforcement' target=_blank>documentation</a> for more information.",
|
||||
s.ID(),
|
||||
ds.UID,
|
||||
), nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type healthCheckStep struct {
|
||||
PluginContextProvider pluginContextProvider
|
||||
PluginClient plugins.Client
|
||||
}
|
||||
|
||||
func (s *healthCheckStep) Title() string {
|
||||
return "Health check"
|
||||
}
|
||||
|
||||
func (s *healthCheckStep) Description() string {
|
||||
return "Check if all data sources are healthy."
|
||||
}
|
||||
|
||||
func (s *healthCheckStep) ID() string {
|
||||
return "health-check"
|
||||
}
|
||||
|
||||
func (s *healthCheckStep) Run(ctx context.Context, obj *advisor.CheckSpec, i any) (*advisor.CheckReportFailure, error) {
|
||||
ds, ok := i.(*datasources.DataSource)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid item type %T", i)
|
||||
}
|
||||
|
||||
// Health check execution
|
||||
requester, err := identity.GetRequester(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pCtx, err := s.PluginContextProvider.GetWithDataSource(ctx, ds.Type, requester, ds)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get plugin context: %w", err)
|
||||
}
|
||||
req := &backend.CheckHealthRequest{
|
||||
PluginContext: pCtx,
|
||||
Headers: map[string]string{},
|
||||
}
|
||||
resp, err := s.PluginClient.CheckHealth(ctx, req)
|
||||
if err != nil || resp.Status != backend.HealthStatusOk {
|
||||
return checks.NewCheckReportFailure(
|
||||
advisor.CheckReportFailureSeverityHigh,
|
||||
fmt.Sprintf("Health check failed for %s", ds.Name),
|
||||
fmt.Sprintf(
|
||||
"Go to the <a href='/connections/datasources/edit/%s'>data source configuration</a>"+
|
||||
" and address the issues reported.", ds.UID),
|
||||
s.ID(),
|
||||
ds.UID,
|
||||
), nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type pluginContextProvider interface {
|
||||
GetWithDataSource(ctx context.Context, pluginID string, user identity.Requester, ds *datasources.DataSource) (backend.PluginContext, error)
|
||||
}
|
||||
149
apps/advisor/pkg/app/checks/datasourcecheck/check_test.go
Normal file
149
apps/advisor/pkg/app/checks/datasourcecheck/check_test.go
Normal file
@@ -0,0 +1,149 @@
|
||||
package datasourcecheck
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
advisor "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCheck_Run(t *testing.T) {
|
||||
t.Run("should return no failures when all datasources are healthy", func(t *testing.T) {
|
||||
datasources := []*datasources.DataSource{
|
||||
{UID: "valid-uid-1", Type: "prometheus", Name: "Prometheus"},
|
||||
{UID: "valid-uid-2", Type: "mysql", Name: "MySQL"},
|
||||
}
|
||||
|
||||
mockDatasourceSvc := &MockDatasourceSvc{dss: datasources}
|
||||
mockPluginContextProvider := &MockPluginContextProvider{pCtx: backend.PluginContext{}}
|
||||
mockPluginClient := &MockPluginClient{res: &backend.CheckHealthResult{Status: backend.HealthStatusOk}}
|
||||
|
||||
check := &check{
|
||||
DatasourceSvc: mockDatasourceSvc,
|
||||
PluginContextProvider: mockPluginContextProvider,
|
||||
PluginClient: mockPluginClient,
|
||||
}
|
||||
|
||||
ctx := identity.WithRequester(context.Background(), &user.SignedInUser{})
|
||||
items, err := check.Items(ctx)
|
||||
assert.NoError(t, err)
|
||||
failures := []advisor.CheckReportFailure{}
|
||||
for _, step := range check.Steps() {
|
||||
for _, item := range items {
|
||||
stepFailures, err := step.Run(ctx, &advisor.CheckSpec{}, item)
|
||||
assert.NoError(t, err)
|
||||
if stepFailures != nil {
|
||||
failures = append(failures, *stepFailures)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 2, len(items))
|
||||
assert.Empty(t, failures)
|
||||
})
|
||||
|
||||
t.Run("should return failures when datasource UID is invalid", func(t *testing.T) {
|
||||
datasources := []*datasources.DataSource{
|
||||
{UID: "invalid uid", Type: "prometheus", Name: "Prometheus"},
|
||||
}
|
||||
|
||||
mockDatasourceSvc := &MockDatasourceSvc{dss: datasources}
|
||||
mockPluginContextProvider := &MockPluginContextProvider{pCtx: backend.PluginContext{}}
|
||||
mockPluginClient := &MockPluginClient{res: &backend.CheckHealthResult{Status: backend.HealthStatusOk}}
|
||||
|
||||
check := &check{
|
||||
DatasourceSvc: mockDatasourceSvc,
|
||||
PluginContextProvider: mockPluginContextProvider,
|
||||
PluginClient: mockPluginClient,
|
||||
}
|
||||
|
||||
ctx := identity.WithRequester(context.Background(), &user.SignedInUser{})
|
||||
items, err := check.Items(ctx)
|
||||
assert.NoError(t, err)
|
||||
failures := []advisor.CheckReportFailure{}
|
||||
for _, step := range check.Steps() {
|
||||
for _, item := range items {
|
||||
stepFailures, err := step.Run(ctx, &advisor.CheckSpec{}, item)
|
||||
assert.NoError(t, err)
|
||||
if stepFailures != nil {
|
||||
failures = append(failures, *stepFailures)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, len(items))
|
||||
assert.Len(t, failures, 1)
|
||||
assert.Equal(t, "Invalid UID 'invalid uid' for data source Prometheus", failures[0].Reason)
|
||||
})
|
||||
|
||||
t.Run("should return failures when datasource health check fails", func(t *testing.T) {
|
||||
datasources := []*datasources.DataSource{
|
||||
{UID: "valid-uid-1", Type: "prometheus", Name: "Prometheus"},
|
||||
}
|
||||
|
||||
mockDatasourceSvc := &MockDatasourceSvc{dss: datasources}
|
||||
mockPluginContextProvider := &MockPluginContextProvider{pCtx: backend.PluginContext{}}
|
||||
mockPluginClient := &MockPluginClient{res: &backend.CheckHealthResult{Status: backend.HealthStatusError}}
|
||||
|
||||
check := &check{
|
||||
DatasourceSvc: mockDatasourceSvc,
|
||||
PluginContextProvider: mockPluginContextProvider,
|
||||
PluginClient: mockPluginClient,
|
||||
}
|
||||
|
||||
ctx := identity.WithRequester(context.Background(), &user.SignedInUser{})
|
||||
items, err := check.Items(ctx)
|
||||
assert.NoError(t, err)
|
||||
failures := []advisor.CheckReportFailure{}
|
||||
for _, step := range check.Steps() {
|
||||
for _, item := range items {
|
||||
stepFailures, err := step.Run(ctx, &advisor.CheckSpec{}, item)
|
||||
assert.NoError(t, err)
|
||||
if stepFailures != nil {
|
||||
failures = append(failures, *stepFailures)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, len(items))
|
||||
assert.Len(t, failures, 1)
|
||||
assert.Equal(t, "Health check failed for Prometheus", failures[0].Reason)
|
||||
})
|
||||
}
|
||||
|
||||
type MockDatasourceSvc struct {
|
||||
datasources.DataSourceService
|
||||
|
||||
dss []*datasources.DataSource
|
||||
}
|
||||
|
||||
func (m *MockDatasourceSvc) GetAllDataSources(ctx context.Context, query *datasources.GetAllDataSourcesQuery) ([]*datasources.DataSource, error) {
|
||||
return m.dss, nil
|
||||
}
|
||||
|
||||
type MockPluginContextProvider struct {
|
||||
pCtx backend.PluginContext
|
||||
}
|
||||
|
||||
func (m *MockPluginContextProvider) GetWithDataSource(ctx context.Context, pluginID string, user identity.Requester, ds *datasources.DataSource) (backend.PluginContext, error) {
|
||||
return m.pCtx, nil
|
||||
}
|
||||
|
||||
type MockPluginClient struct {
|
||||
plugins.Client
|
||||
|
||||
res *backend.CheckHealthResult
|
||||
}
|
||||
|
||||
func (m *MockPluginClient) CheckHealth(ctx context.Context, req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) {
|
||||
return m.res, nil
|
||||
}
|
||||
29
apps/advisor/pkg/app/checks/ifaces.go
Normal file
29
apps/advisor/pkg/app/checks/ifaces.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package checks
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
|
||||
)
|
||||
|
||||
// Check returns metadata about the check being executed and the list of Steps
|
||||
type Check interface {
|
||||
// ID returns the unique identifier of the check
|
||||
ID() string
|
||||
// Items returns the list of items that will be checked
|
||||
Items(ctx context.Context) ([]any, error)
|
||||
// Steps returns the list of steps that will be executed
|
||||
Steps() []Step
|
||||
}
|
||||
|
||||
// Step is a single step in a check, including its metadata
|
||||
type Step interface {
|
||||
// ID returns the unique identifier of the step
|
||||
ID() string
|
||||
// Title returns the title of the step
|
||||
Title() string
|
||||
// Description returns the description of the step
|
||||
Description() string
|
||||
// Run executes the step for an item and returns a report
|
||||
Run(ctx context.Context, obj *advisorv0alpha1.CheckSpec, item any) (*advisorv0alpha1.CheckReportFailure, error)
|
||||
}
|
||||
184
apps/advisor/pkg/app/checks/plugincheck/check.go
Normal file
184
apps/advisor/pkg/app/checks/plugincheck/check.go
Normal file
@@ -0,0 +1,184 @@
|
||||
package plugincheck
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
sysruntime "runtime"
|
||||
|
||||
"github.com/Masterminds/semver/v3"
|
||||
advisor "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/app/checks"
|
||||
"github.com/grafana/grafana/pkg/cmd/grafana-cli/services"
|
||||
"github.com/grafana/grafana/pkg/plugins/repo"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/managedplugins"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/plugininstaller"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
||||
)
|
||||
|
||||
func New(
|
||||
pluginStore pluginstore.Store,
|
||||
pluginRepo repo.Service,
|
||||
pluginPreinstall plugininstaller.Preinstall,
|
||||
managedPlugins managedplugins.Manager,
|
||||
) checks.Check {
|
||||
return &check{
|
||||
PluginStore: pluginStore,
|
||||
PluginRepo: pluginRepo,
|
||||
PluginPreinstall: pluginPreinstall,
|
||||
ManagedPlugins: managedPlugins,
|
||||
}
|
||||
}
|
||||
|
||||
type check struct {
|
||||
PluginStore pluginstore.Store
|
||||
PluginRepo repo.Service
|
||||
PluginPreinstall plugininstaller.Preinstall
|
||||
ManagedPlugins managedplugins.Manager
|
||||
}
|
||||
|
||||
func (c *check) ID() string {
|
||||
return "plugin"
|
||||
}
|
||||
|
||||
func (c *check) Items(ctx context.Context) ([]any, error) {
|
||||
ps := c.PluginStore.Plugins(ctx)
|
||||
res := make([]any, len(ps))
|
||||
for i, p := range ps {
|
||||
res[i] = p
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (c *check) Steps() []checks.Step {
|
||||
return []checks.Step{
|
||||
&deprecationStep{
|
||||
PluginRepo: c.PluginRepo,
|
||||
},
|
||||
&updateStep{
|
||||
PluginRepo: c.PluginRepo,
|
||||
PluginPreinstall: c.PluginPreinstall,
|
||||
ManagedPlugins: c.ManagedPlugins,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type deprecationStep struct {
|
||||
PluginRepo repo.Service
|
||||
}
|
||||
|
||||
func (s *deprecationStep) Title() string {
|
||||
return "Deprecation check"
|
||||
}
|
||||
|
||||
func (s *deprecationStep) Description() string {
|
||||
return "Check if any installed plugins are deprecated."
|
||||
}
|
||||
|
||||
func (s *deprecationStep) ID() string {
|
||||
return "deprecation"
|
||||
}
|
||||
|
||||
func (s *deprecationStep) Run(ctx context.Context, _ *advisor.CheckSpec, it any) (*advisor.CheckReportFailure, error) {
|
||||
p, ok := it.(pluginstore.Plugin)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid item type %T", it)
|
||||
}
|
||||
|
||||
// Skip if it's a core plugin
|
||||
if p.IsCorePlugin() {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Check if plugin is deprecated
|
||||
i, err := s.PluginRepo.PluginInfo(ctx, p.ID)
|
||||
if err != nil {
|
||||
// Unable to check deprecation status
|
||||
return nil, nil
|
||||
}
|
||||
if i.Status == "deprecated" {
|
||||
return checks.NewCheckReportFailure(
|
||||
advisor.CheckReportFailureSeverityHigh,
|
||||
fmt.Sprintf("Plugin deprecated: %s", p.ID),
|
||||
"Check the <a href='https://grafana.com/legal/plugin-deprecation/#a-plugin-i-use-is-deprecated-what-should-i-do' target=_blank>documentation</a> for recommended steps.",
|
||||
s.ID(),
|
||||
p.ID,
|
||||
), nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type updateStep struct {
|
||||
PluginRepo repo.Service
|
||||
PluginPreinstall plugininstaller.Preinstall
|
||||
ManagedPlugins managedplugins.Manager
|
||||
}
|
||||
|
||||
func (s *updateStep) Title() string {
|
||||
return "Update check"
|
||||
}
|
||||
|
||||
func (s *updateStep) Description() string {
|
||||
return "Check if any installed plugins have a newer version available."
|
||||
}
|
||||
|
||||
func (s *updateStep) ID() string {
|
||||
return "update"
|
||||
}
|
||||
|
||||
func (s *updateStep) Run(ctx context.Context, _ *advisor.CheckSpec, i any) (*advisor.CheckReportFailure, error) {
|
||||
p, ok := i.(pluginstore.Plugin)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid item type %T", i)
|
||||
}
|
||||
|
||||
// Skip if it's a core plugin
|
||||
if p.IsCorePlugin() {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Skip if it's managed or pinned
|
||||
if s.isManaged(ctx, p.ID) || s.PluginPreinstall.IsPinned(p.ID) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Check if plugin has a newer version available
|
||||
compatOpts := repo.NewCompatOpts(services.GrafanaVersion, sysruntime.GOOS, sysruntime.GOARCH)
|
||||
info, err := s.PluginRepo.GetPluginArchiveInfo(ctx, p.ID, "", compatOpts)
|
||||
if err != nil {
|
||||
// Unable to check updates
|
||||
return nil, nil
|
||||
}
|
||||
if hasUpdate(p, info) {
|
||||
return checks.NewCheckReportFailure(
|
||||
advisor.CheckReportFailureSeverityLow,
|
||||
fmt.Sprintf("New version available for %s", p.ID),
|
||||
fmt.Sprintf(
|
||||
"Go to the <a href='/plugins/%s?page=version-history'>plugin admin page</a>"+
|
||||
" and upgrade to the latest version.", p.ID),
|
||||
s.ID(),
|
||||
p.ID,
|
||||
), nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func hasUpdate(current pluginstore.Plugin, latest *repo.PluginArchiveInfo) bool {
|
||||
// If both versions are semver-valid, compare them
|
||||
v1, err1 := semver.NewVersion(current.Info.Version)
|
||||
v2, err2 := semver.NewVersion(latest.Version)
|
||||
if err1 == nil && err2 == nil {
|
||||
return v1.LessThan(v2)
|
||||
}
|
||||
// In other case, assume that a different latest version will always be newer
|
||||
return current.Info.Version != latest.Version
|
||||
}
|
||||
|
||||
func (s *updateStep) isManaged(ctx context.Context, pluginID string) bool {
|
||||
for _, managedPlugin := range s.ManagedPlugins.ManagedPlugins(ctx) {
|
||||
if managedPlugin == pluginID {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
198
apps/advisor/pkg/app/checks/plugincheck/check_test.go
Normal file
198
apps/advisor/pkg/app/checks/plugincheck/check_test.go
Normal file
@@ -0,0 +1,198 @@
|
||||
package plugincheck
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
advisor "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/plugins/repo"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/managedplugins"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/plugininstaller"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestRun(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
plugins []pluginstore.Plugin
|
||||
pluginInfo map[string]*repo.PluginInfo
|
||||
pluginArchives map[string]*repo.PluginArchiveInfo
|
||||
pluginPreinstalled []string
|
||||
pluginManaged []string
|
||||
expectedFailures []advisor.CheckReportFailure
|
||||
}{
|
||||
{
|
||||
name: "No plugins",
|
||||
plugins: []pluginstore.Plugin{},
|
||||
expectedFailures: []advisor.CheckReportFailure{},
|
||||
},
|
||||
{
|
||||
name: "Deprecated plugin",
|
||||
plugins: []pluginstore.Plugin{
|
||||
{JSONData: plugins.JSONData{ID: "plugin1", Info: plugins.Info{Version: "1.0.0"}}},
|
||||
},
|
||||
pluginInfo: map[string]*repo.PluginInfo{
|
||||
"plugin1": {Status: "deprecated"},
|
||||
},
|
||||
pluginArchives: map[string]*repo.PluginArchiveInfo{
|
||||
"plugin1": {Version: "1.0.0"},
|
||||
},
|
||||
expectedFailures: []advisor.CheckReportFailure{
|
||||
{
|
||||
Severity: advisor.CheckReportFailureSeverityHigh,
|
||||
Reason: "Plugin deprecated: plugin1",
|
||||
Action: "Check the <a href='https://grafana.com/legal/plugin-deprecation/#a-plugin-i-use-is-deprecated-what-should-i-do' target=_blank>documentation</a> for recommended steps.",
|
||||
StepID: "deprecation",
|
||||
ItemID: "plugin1",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Plugin with update",
|
||||
plugins: []pluginstore.Plugin{
|
||||
{JSONData: plugins.JSONData{ID: "plugin2", Info: plugins.Info{Version: "1.0.0"}}},
|
||||
},
|
||||
pluginInfo: map[string]*repo.PluginInfo{
|
||||
"plugin2": {Status: "active"},
|
||||
},
|
||||
pluginArchives: map[string]*repo.PluginArchiveInfo{
|
||||
"plugin2": {Version: "1.1.0"},
|
||||
},
|
||||
expectedFailures: []advisor.CheckReportFailure{
|
||||
{
|
||||
Severity: advisor.CheckReportFailureSeverityLow,
|
||||
Reason: "New version available for plugin2",
|
||||
Action: "Go to the <a href='/plugins/plugin2?page=version-history'>plugin admin page</a> and upgrade to the latest version.",
|
||||
StepID: "update",
|
||||
ItemID: "plugin2",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Plugin with update (non semver)",
|
||||
plugins: []pluginstore.Plugin{
|
||||
{JSONData: plugins.JSONData{ID: "plugin2", Info: plugins.Info{Version: "alpha"}}},
|
||||
},
|
||||
pluginInfo: map[string]*repo.PluginInfo{
|
||||
"plugin2": {Status: "active"},
|
||||
},
|
||||
pluginArchives: map[string]*repo.PluginArchiveInfo{
|
||||
"plugin2": {Version: "beta"},
|
||||
},
|
||||
expectedFailures: []advisor.CheckReportFailure{
|
||||
{
|
||||
Severity: advisor.CheckReportFailureSeverityLow,
|
||||
Reason: "New version available for plugin2",
|
||||
Action: "Go to the <a href='/plugins/plugin2?page=version-history'>plugin admin page</a> and upgrade to the latest version.",
|
||||
StepID: "update",
|
||||
ItemID: "plugin2",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Plugin pinned",
|
||||
plugins: []pluginstore.Plugin{
|
||||
{JSONData: plugins.JSONData{ID: "plugin3", Info: plugins.Info{Version: "1.0.0"}}},
|
||||
},
|
||||
pluginInfo: map[string]*repo.PluginInfo{
|
||||
"plugin3": {Status: "active"},
|
||||
},
|
||||
pluginArchives: map[string]*repo.PluginArchiveInfo{
|
||||
"plugin3": {Version: "1.1.0"},
|
||||
},
|
||||
pluginPreinstalled: []string{"plugin3"},
|
||||
expectedFailures: []advisor.CheckReportFailure{},
|
||||
},
|
||||
{
|
||||
name: "Managed plugin",
|
||||
plugins: []pluginstore.Plugin{
|
||||
{JSONData: plugins.JSONData{ID: "plugin4", Info: plugins.Info{Version: "1.0.0"}}},
|
||||
},
|
||||
pluginInfo: map[string]*repo.PluginInfo{
|
||||
"plugin4": {Status: "active"},
|
||||
},
|
||||
pluginArchives: map[string]*repo.PluginArchiveInfo{
|
||||
"plugin4": {Version: "1.1.0"},
|
||||
},
|
||||
pluginManaged: []string{"plugin4"},
|
||||
expectedFailures: []advisor.CheckReportFailure{},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
pluginStore := &mockPluginStore{plugins: tt.plugins}
|
||||
pluginRepo := &mockPluginRepo{
|
||||
pluginInfo: tt.pluginInfo,
|
||||
pluginArchiveInfo: tt.pluginArchives,
|
||||
}
|
||||
pluginPreinstall := &mockPluginPreinstall{pinned: tt.pluginPreinstalled}
|
||||
managedPlugins := &mockManagedPlugins{managed: tt.pluginManaged}
|
||||
check := New(pluginStore, pluginRepo, pluginPreinstall, managedPlugins)
|
||||
|
||||
items, err := check.Items(context.Background())
|
||||
assert.NoError(t, err)
|
||||
failures := []advisor.CheckReportFailure{}
|
||||
for _, step := range check.Steps() {
|
||||
for _, item := range items {
|
||||
stepFailures, err := step.Run(context.Background(), &advisor.CheckSpec{}, item)
|
||||
assert.NoError(t, err)
|
||||
if stepFailures != nil {
|
||||
failures = append(failures, *stepFailures)
|
||||
}
|
||||
}
|
||||
}
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, len(tt.plugins), len(items))
|
||||
assert.Equal(t, tt.expectedFailures, failures)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type mockPluginStore struct {
|
||||
pluginstore.Store
|
||||
plugins []pluginstore.Plugin
|
||||
}
|
||||
|
||||
func (m *mockPluginStore) Plugins(ctx context.Context, t ...plugins.Type) []pluginstore.Plugin {
|
||||
return m.plugins
|
||||
}
|
||||
|
||||
type mockPluginRepo struct {
|
||||
repo.Service
|
||||
pluginInfo map[string]*repo.PluginInfo
|
||||
pluginArchiveInfo map[string]*repo.PluginArchiveInfo
|
||||
}
|
||||
|
||||
func (m *mockPluginRepo) PluginInfo(ctx context.Context, id string) (*repo.PluginInfo, error) {
|
||||
return m.pluginInfo[id], nil
|
||||
}
|
||||
|
||||
func (m *mockPluginRepo) GetPluginArchiveInfo(ctx context.Context, id, version string, opts repo.CompatOpts) (*repo.PluginArchiveInfo, error) {
|
||||
return m.pluginArchiveInfo[id], nil
|
||||
}
|
||||
|
||||
type mockPluginPreinstall struct {
|
||||
plugininstaller.Preinstall
|
||||
pinned []string
|
||||
}
|
||||
|
||||
func (m *mockPluginPreinstall) IsPinned(pluginID string) bool {
|
||||
for _, p := range m.pinned {
|
||||
if p == pluginID {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type mockManagedPlugins struct {
|
||||
managedplugins.Manager
|
||||
managed []string
|
||||
}
|
||||
|
||||
func (m *mockManagedPlugins) ManagedPlugins(ctx context.Context) []string {
|
||||
return m.managed
|
||||
}
|
||||
26
apps/advisor/pkg/app/checks/utils.go
Normal file
26
apps/advisor/pkg/app/checks/utils.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package checks
|
||||
|
||||
import (
|
||||
advisor "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
|
||||
)
|
||||
|
||||
const (
|
||||
TypeLabel = "advisor.grafana.app/type"
|
||||
StatusAnnotation = "advisor.grafana.app/status"
|
||||
)
|
||||
|
||||
func NewCheckReportFailure(
|
||||
severity advisor.CheckReportFailureSeverity,
|
||||
reason string,
|
||||
action string,
|
||||
stepID string,
|
||||
itemID string,
|
||||
) *advisor.CheckReportFailure {
|
||||
return &advisor.CheckReportFailure{
|
||||
Severity: severity,
|
||||
Reason: reason,
|
||||
Action: action,
|
||||
StepID: stepID,
|
||||
ItemID: itemID,
|
||||
}
|
||||
}
|
||||
219
apps/advisor/pkg/app/checkscheduler/checkscheduler.go
Normal file
219
apps/advisor/pkg/app/checkscheduler/checkscheduler.go
Normal file
@@ -0,0 +1,219 @@
|
||||
package checkscheduler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana-app-sdk/app"
|
||||
"github.com/grafana/grafana-app-sdk/k8s"
|
||||
"github.com/grafana/grafana-app-sdk/resource"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/gtime"
|
||||
advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/app/checkregistry"
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/app/checks"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
const defaultEvaluationInterval = 24 * time.Hour
|
||||
const defaultMaxHistory = 10
|
||||
|
||||
// Runner is a "runnable" app used to be able to expose and API endpoint
|
||||
// with the existing checks types. This does not need to be a CRUD resource, but it is
|
||||
// the only way existing at the moment to expose the check types.
|
||||
type Runner struct {
|
||||
checkRegistry checkregistry.CheckService
|
||||
client resource.Client
|
||||
evaluationInterval time.Duration
|
||||
maxHistory int
|
||||
}
|
||||
|
||||
// NewRunner creates a new Runner.
|
||||
func New(cfg app.Config) (app.Runnable, error) {
|
||||
// Read config
|
||||
specificConfig, ok := cfg.SpecificConfig.(checkregistry.AdvisorAppConfig)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid config type")
|
||||
}
|
||||
checkRegistry := specificConfig.CheckRegistry
|
||||
evalInterval, err := getEvaluationInterval(specificConfig.PluginConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
maxHistory, err := getMaxHistory(specificConfig.PluginConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Prepare storage client
|
||||
clientGenerator := k8s.NewClientRegistry(cfg.KubeConfig, k8s.ClientConfig{})
|
||||
client, err := clientGenerator.ClientFor(advisorv0alpha1.CheckKind())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Runner{
|
||||
checkRegistry: checkRegistry,
|
||||
client: client,
|
||||
evaluationInterval: evalInterval,
|
||||
maxHistory: maxHistory,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r *Runner) Run(ctx context.Context) error {
|
||||
lastCreated, err := r.checkLastCreated(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// do an initial creation if necessary
|
||||
if lastCreated.IsZero() {
|
||||
err = r.createChecks(ctx)
|
||||
if err != nil {
|
||||
klog.Error("Error creating new check reports", "error", err)
|
||||
} else {
|
||||
lastCreated = time.Now()
|
||||
}
|
||||
}
|
||||
|
||||
nextSendInterval := time.Until(lastCreated.Add(r.evaluationInterval))
|
||||
if nextSendInterval < time.Minute {
|
||||
nextSendInterval = 1 * time.Minute
|
||||
}
|
||||
|
||||
ticker := time.NewTicker(nextSendInterval)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
err = r.createChecks(ctx)
|
||||
if err != nil {
|
||||
klog.Error("Error creating new check reports", "error", err)
|
||||
}
|
||||
|
||||
err = r.cleanupChecks(ctx)
|
||||
if err != nil {
|
||||
klog.Error("Error cleaning up old check reports", "error", err)
|
||||
}
|
||||
|
||||
if nextSendInterval != r.evaluationInterval {
|
||||
nextSendInterval = r.evaluationInterval
|
||||
}
|
||||
ticker.Reset(nextSendInterval)
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// checkLastCreated returns the creation time of the last check created
|
||||
// regardless of its ID. This assumes that the checks are created in batches
|
||||
// so a batch will have a similar creation time.
|
||||
func (r *Runner) checkLastCreated(ctx context.Context) (time.Time, error) {
|
||||
list, err := r.client.List(ctx, metav1.NamespaceDefault, resource.ListOptions{})
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
lastCreated := time.Time{}
|
||||
for _, item := range list.GetItems() {
|
||||
itemCreated := item.GetCreationTimestamp().Time
|
||||
if itemCreated.After(lastCreated) {
|
||||
lastCreated = itemCreated
|
||||
}
|
||||
}
|
||||
return lastCreated, nil
|
||||
}
|
||||
|
||||
// createChecks creates a new check for each check type in the registry.
|
||||
func (r *Runner) createChecks(ctx context.Context) error {
|
||||
for _, check := range r.checkRegistry.Checks() {
|
||||
obj := &advisorv0alpha1.Check{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
GenerateName: "check-",
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Labels: map[string]string{
|
||||
checks.TypeLabel: check.ID(),
|
||||
},
|
||||
},
|
||||
Spec: advisorv0alpha1.CheckSpec{},
|
||||
}
|
||||
id := obj.GetStaticMetadata().Identifier()
|
||||
_, err := r.client.Create(ctx, id, obj, resource.CreateOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating check: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// cleanupChecks deletes the olders checks if the number of checks exceeds the limit.
|
||||
func (r *Runner) cleanupChecks(ctx context.Context) error {
|
||||
list, err := r.client.List(ctx, metav1.NamespaceDefault, resource.ListOptions{Limit: -1})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// organize checks by type
|
||||
checksByType := map[string][]resource.Object{}
|
||||
for _, check := range list.GetItems() {
|
||||
labels := check.GetLabels()
|
||||
checkType, ok := labels[checks.TypeLabel]
|
||||
if !ok {
|
||||
klog.Error("Check type not found in labels", "check", check)
|
||||
continue
|
||||
}
|
||||
checksByType[checkType] = append(checksByType[checkType], check)
|
||||
}
|
||||
|
||||
for _, checks := range checksByType {
|
||||
if len(checks) > r.maxHistory {
|
||||
// Sort checks by creation time
|
||||
sort.Slice(checks, func(i, j int) bool {
|
||||
ti := checks[i].GetCreationTimestamp().Time
|
||||
tj := checks[j].GetCreationTimestamp().Time
|
||||
return ti.Before(tj)
|
||||
})
|
||||
// Delete the oldest checks
|
||||
for i := 0; i < len(checks)-r.maxHistory; i++ {
|
||||
check := checks[i]
|
||||
id := check.GetStaticMetadata().Identifier()
|
||||
err := r.client.Delete(ctx, id, resource.DeleteOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("error deleting check: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getEvaluationInterval(pluginConfig map[string]string) (time.Duration, error) {
|
||||
evaluationInterval := defaultEvaluationInterval
|
||||
configEvaluationInterval, ok := pluginConfig["evaluation_interval"]
|
||||
if ok {
|
||||
var err error
|
||||
evaluationInterval, err = gtime.ParseDuration(configEvaluationInterval)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("invalid evaluation interval: %w", err)
|
||||
}
|
||||
}
|
||||
return evaluationInterval, nil
|
||||
}
|
||||
|
||||
func getMaxHistory(pluginConfig map[string]string) (int, error) {
|
||||
maxHistory := defaultMaxHistory
|
||||
configMaxHistory, ok := pluginConfig["max_history"]
|
||||
if ok {
|
||||
var err error
|
||||
maxHistory, err = strconv.Atoi(configMaxHistory)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("invalid max history: %w", err)
|
||||
}
|
||||
}
|
||||
return maxHistory, nil
|
||||
}
|
||||
279
apps/advisor/pkg/app/checkscheduler/checkscheduler_test.go
Normal file
279
apps/advisor/pkg/app/checkscheduler/checkscheduler_test.go
Normal file
@@ -0,0 +1,279 @@
|
||||
package checkscheduler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand/v2"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana-app-sdk/resource"
|
||||
advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/app/checks"
|
||||
"github.com/stretchr/testify/assert"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func TestRunner_Run_ErrorOnList(t *testing.T) {
|
||||
mockCheckService := &MockCheckService{}
|
||||
mockClient := &MockClient{
|
||||
listFunc: func(ctx context.Context, namespace string, options resource.ListOptions) (resource.ListObject, error) {
|
||||
return nil, errors.New("list error")
|
||||
},
|
||||
createFunc: func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.CreateOptions) (resource.Object, error) {
|
||||
return &advisorv0alpha1.Check{}, nil
|
||||
},
|
||||
}
|
||||
|
||||
runner := &Runner{
|
||||
checkRegistry: mockCheckService,
|
||||
client: mockClient,
|
||||
}
|
||||
|
||||
err := runner.Run(context.Background())
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestRunner_checkLastCreated_ErrorOnList(t *testing.T) {
|
||||
mockClient := &MockClient{
|
||||
listFunc: func(ctx context.Context, namespace string, options resource.ListOptions) (resource.ListObject, error) {
|
||||
return nil, errors.New("list error")
|
||||
},
|
||||
}
|
||||
|
||||
runner := &Runner{
|
||||
client: mockClient,
|
||||
}
|
||||
|
||||
lastCreated, err := runner.checkLastCreated(context.Background())
|
||||
assert.Error(t, err)
|
||||
assert.True(t, lastCreated.IsZero())
|
||||
}
|
||||
|
||||
func TestRunner_createChecks_ErrorOnCreate(t *testing.T) {
|
||||
mockCheckService := &MockCheckService{
|
||||
checks: []checks.Check{
|
||||
&mockCheck{
|
||||
id: "check-1",
|
||||
},
|
||||
},
|
||||
}
|
||||
mockClient := &MockClient{
|
||||
createFunc: func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.CreateOptions) (resource.Object, error) {
|
||||
return nil, errors.New("create error")
|
||||
},
|
||||
}
|
||||
|
||||
runner := &Runner{
|
||||
checkRegistry: mockCheckService,
|
||||
client: mockClient,
|
||||
}
|
||||
|
||||
err := runner.createChecks(context.Background())
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestRunner_createChecks_Success(t *testing.T) {
|
||||
mockCheckService := &MockCheckService{
|
||||
checks: []checks.Check{
|
||||
&mockCheck{
|
||||
id: "check-1",
|
||||
},
|
||||
},
|
||||
}
|
||||
mockClient := &MockClient{
|
||||
createFunc: func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.CreateOptions) (resource.Object, error) {
|
||||
return &advisorv0alpha1.Check{}, nil
|
||||
},
|
||||
}
|
||||
|
||||
runner := &Runner{
|
||||
checkRegistry: mockCheckService,
|
||||
client: mockClient,
|
||||
}
|
||||
|
||||
err := runner.createChecks(context.Background())
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestRunner_cleanupChecks_ErrorOnList(t *testing.T) {
|
||||
mockClient := &MockClient{
|
||||
listFunc: func(ctx context.Context, namespace string, options resource.ListOptions) (resource.ListObject, error) {
|
||||
return nil, errors.New("list error")
|
||||
},
|
||||
}
|
||||
|
||||
runner := &Runner{
|
||||
client: mockClient,
|
||||
}
|
||||
|
||||
err := runner.cleanupChecks(context.Background())
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestRunner_cleanupChecks_WithinMax(t *testing.T) {
|
||||
mockClient := &MockClient{
|
||||
listFunc: func(ctx context.Context, namespace string, options resource.ListOptions) (resource.ListObject, error) {
|
||||
return &advisorv0alpha1.CheckList{
|
||||
Items: []advisorv0alpha1.Check{{}, {}},
|
||||
}, nil
|
||||
},
|
||||
deleteFunc: func(ctx context.Context, identifier resource.Identifier, options resource.DeleteOptions) error {
|
||||
return fmt.Errorf("shouldn't be called")
|
||||
},
|
||||
}
|
||||
|
||||
runner := &Runner{
|
||||
client: mockClient,
|
||||
}
|
||||
|
||||
err := runner.cleanupChecks(context.Background())
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestRunner_cleanupChecks_ErrorOnDelete(t *testing.T) {
|
||||
mockClient := &MockClient{
|
||||
listFunc: func(ctx context.Context, namespace string, options resource.ListOptions) (resource.ListObject, error) {
|
||||
items := make([]advisorv0alpha1.Check, 0, defaultMaxHistory+1)
|
||||
for i := 0; i < defaultMaxHistory+1; i++ {
|
||||
item := advisorv0alpha1.Check{}
|
||||
item.ObjectMeta.SetLabels(map[string]string{
|
||||
checks.TypeLabel: "mock",
|
||||
})
|
||||
items = append(items, item)
|
||||
}
|
||||
return &advisorv0alpha1.CheckList{
|
||||
Items: items,
|
||||
}, nil
|
||||
},
|
||||
deleteFunc: func(ctx context.Context, identifier resource.Identifier, options resource.DeleteOptions) error {
|
||||
return errors.New("delete error")
|
||||
},
|
||||
}
|
||||
|
||||
runner := &Runner{
|
||||
client: mockClient,
|
||||
maxHistory: defaultMaxHistory,
|
||||
}
|
||||
err := runner.cleanupChecks(context.Background())
|
||||
assert.ErrorContains(t, err, "delete error")
|
||||
}
|
||||
|
||||
func TestRunner_cleanupChecks_Success(t *testing.T) {
|
||||
itemsDeleted := []string{}
|
||||
items := make([]advisorv0alpha1.Check, 0, defaultMaxHistory+1)
|
||||
for i := 0; i < defaultMaxHistory+1; i++ {
|
||||
item := advisorv0alpha1.Check{}
|
||||
item.ObjectMeta.SetName(fmt.Sprintf("check-%d", i))
|
||||
item.ObjectMeta.SetLabels(map[string]string{
|
||||
checks.TypeLabel: "mock",
|
||||
})
|
||||
item.ObjectMeta.SetCreationTimestamp(metav1.NewTime(time.Time{}.Add(time.Duration(i) * time.Hour)))
|
||||
items = append(items, item)
|
||||
}
|
||||
// shuffle the items to ensure the oldest are deleted
|
||||
rand.Shuffle(len(items), func(i, j int) { items[i], items[j] = items[j], items[i] })
|
||||
|
||||
mockClient := &MockClient{
|
||||
listFunc: func(ctx context.Context, namespace string, options resource.ListOptions) (resource.ListObject, error) {
|
||||
return &advisorv0alpha1.CheckList{
|
||||
Items: items,
|
||||
}, nil
|
||||
},
|
||||
deleteFunc: func(ctx context.Context, identifier resource.Identifier, options resource.DeleteOptions) error {
|
||||
itemsDeleted = append(itemsDeleted, identifier.Name)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
runner := &Runner{
|
||||
client: mockClient,
|
||||
maxHistory: defaultMaxHistory,
|
||||
}
|
||||
err := runner.cleanupChecks(context.Background())
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, []string{"check-0"}, itemsDeleted)
|
||||
}
|
||||
|
||||
func Test_getEvaluationInterval(t *testing.T) {
|
||||
t.Run("default", func(t *testing.T) {
|
||||
interval, err := getEvaluationInterval(map[string]string{})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 24*time.Hour, interval)
|
||||
})
|
||||
|
||||
t.Run("invalid", func(t *testing.T) {
|
||||
interval, err := getEvaluationInterval(map[string]string{"evaluation_interval": "invalid"})
|
||||
assert.Error(t, err)
|
||||
assert.Zero(t, interval)
|
||||
})
|
||||
|
||||
t.Run("custom", func(t *testing.T) {
|
||||
interval, err := getEvaluationInterval(map[string]string{"evaluation_interval": "1h"})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, time.Hour, interval)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_getMaxHistory(t *testing.T) {
|
||||
t.Run("default", func(t *testing.T) {
|
||||
history, err := getMaxHistory(map[string]string{})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 10, history)
|
||||
})
|
||||
|
||||
t.Run("invalid", func(t *testing.T) {
|
||||
history, err := getMaxHistory(map[string]string{"max_history": "invalid"})
|
||||
assert.Error(t, err)
|
||||
assert.Zero(t, history)
|
||||
})
|
||||
|
||||
t.Run("custom", func(t *testing.T) {
|
||||
history, err := getMaxHistory(map[string]string{"max_history": "5"})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 5, history)
|
||||
})
|
||||
}
|
||||
|
||||
type MockCheckService struct {
|
||||
checks []checks.Check
|
||||
}
|
||||
|
||||
func (m *MockCheckService) Checks() []checks.Check {
|
||||
return m.checks
|
||||
}
|
||||
|
||||
type MockClient struct {
|
||||
resource.Client
|
||||
listFunc func(ctx context.Context, namespace string, options resource.ListOptions) (resource.ListObject, error)
|
||||
createFunc func(ctx context.Context, identifier resource.Identifier, obj resource.Object, options resource.CreateOptions) (resource.Object, error)
|
||||
deleteFunc func(ctx context.Context, identifier resource.Identifier, options resource.DeleteOptions) error
|
||||
}
|
||||
|
||||
func (m *MockClient) List(ctx context.Context, namespace string, options resource.ListOptions) (resource.ListObject, error) {
|
||||
return m.listFunc(ctx, namespace, options)
|
||||
}
|
||||
|
||||
func (m *MockClient) Create(ctx context.Context, identifier resource.Identifier, obj resource.Object, options resource.CreateOptions) (resource.Object, error) {
|
||||
return m.createFunc(ctx, identifier, obj, options)
|
||||
}
|
||||
|
||||
func (m *MockClient) Delete(ctx context.Context, identifier resource.Identifier, options resource.DeleteOptions) error {
|
||||
return m.deleteFunc(ctx, identifier, options)
|
||||
}
|
||||
|
||||
type mockCheck struct {
|
||||
checks.Check
|
||||
|
||||
id string
|
||||
steps []checks.Step
|
||||
}
|
||||
|
||||
func (m *mockCheck) ID() string {
|
||||
return m.id
|
||||
}
|
||||
|
||||
func (m *mockCheck) Steps() []checks.Step {
|
||||
return m.steps
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package checktyperegisterer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/grafana/grafana-app-sdk/app"
|
||||
"github.com/grafana/grafana-app-sdk/k8s"
|
||||
"github.com/grafana/grafana-app-sdk/resource"
|
||||
advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/app/checkregistry"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// Runner is a "runnable" app used to be able to expose and API endpoint
|
||||
// with the existing checks types. This does not need to be a CRUD resource, but it is
|
||||
// the only way existing at the moment to expose the check types.
|
||||
type Runner struct {
|
||||
checkRegistry checkregistry.CheckService
|
||||
client resource.Client
|
||||
}
|
||||
|
||||
// NewRunner creates a new Runner.
|
||||
func New(cfg app.Config) (app.Runnable, error) {
|
||||
// Read config
|
||||
specificConfig, ok := cfg.SpecificConfig.(checkregistry.AdvisorAppConfig)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid config type")
|
||||
}
|
||||
checkRegistry := specificConfig.CheckRegistry
|
||||
|
||||
// Prepare storage client
|
||||
clientGenerator := k8s.NewClientRegistry(cfg.KubeConfig, k8s.ClientConfig{})
|
||||
client, err := clientGenerator.ClientFor(advisorv0alpha1.CheckTypeKind())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Runner{
|
||||
checkRegistry: checkRegistry,
|
||||
client: client,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r *Runner) Run(ctx context.Context) error {
|
||||
for _, t := range r.checkRegistry.Checks() {
|
||||
steps := t.Steps()
|
||||
stepTypes := make([]advisorv0alpha1.CheckTypeStep, len(steps))
|
||||
for i, s := range steps {
|
||||
stepTypes[i] = advisorv0alpha1.CheckTypeStep{
|
||||
Title: s.Title(),
|
||||
Description: s.Description(),
|
||||
StepID: s.ID(),
|
||||
}
|
||||
}
|
||||
obj := &advisorv0alpha1.CheckType{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: t.ID(),
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
},
|
||||
Spec: advisorv0alpha1.CheckTypeSpec{
|
||||
Name: t.ID(),
|
||||
Steps: stepTypes,
|
||||
},
|
||||
}
|
||||
id := obj.GetStaticMetadata().Identifier()
|
||||
_, err := r.client.Create(ctx, id, obj, resource.CreateOptions{})
|
||||
if err != nil {
|
||||
if errors.IsAlreadyExists(err) {
|
||||
// Already exists, update
|
||||
_, err = r.client.Update(ctx, id, obj, resource.UpdateOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
package checktyperegisterer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana-app-sdk/resource"
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/app/checks"
|
||||
k8sErrs "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
func TestCheckTypesRegisterer_Run(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
checks []checks.Check
|
||||
createFunc func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.CreateOptions) (resource.Object, error)
|
||||
updateFunc func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.UpdateOptions) (resource.Object, error)
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
name: "successful create",
|
||||
checks: []checks.Check{
|
||||
&mockCheck{
|
||||
id: "check1",
|
||||
steps: []checks.Step{
|
||||
&mockStep{id: "step1", title: "Step 1", description: "Description 1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
createFunc: func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.CreateOptions) (resource.Object, error) {
|
||||
return obj, nil
|
||||
},
|
||||
updateFunc: nil,
|
||||
expectedErr: nil,
|
||||
},
|
||||
{
|
||||
name: "create already exists, successful update",
|
||||
checks: []checks.Check{
|
||||
&mockCheck{
|
||||
id: "check1",
|
||||
steps: []checks.Step{
|
||||
&mockStep{id: "step1", title: "Step 1", description: "Description 1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
createFunc: func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.CreateOptions) (resource.Object, error) {
|
||||
return nil, k8sErrs.NewAlreadyExists(schema.GroupResource{}, obj.GetName())
|
||||
},
|
||||
updateFunc: func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.UpdateOptions) (resource.Object, error) {
|
||||
return obj, nil
|
||||
},
|
||||
expectedErr: nil,
|
||||
},
|
||||
{
|
||||
name: "create error",
|
||||
checks: []checks.Check{
|
||||
&mockCheck{
|
||||
id: "check1",
|
||||
steps: []checks.Step{
|
||||
&mockStep{id: "step1", title: "Step 1", description: "Description 1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
createFunc: func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.CreateOptions) (resource.Object, error) {
|
||||
return nil, errors.New("create error")
|
||||
},
|
||||
updateFunc: nil,
|
||||
expectedErr: errors.New("create error"),
|
||||
},
|
||||
{
|
||||
name: "update error",
|
||||
checks: []checks.Check{
|
||||
&mockCheck{
|
||||
id: "check1",
|
||||
steps: []checks.Step{
|
||||
&mockStep{id: "step1", title: "Step 1", description: "Description 1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
createFunc: func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.CreateOptions) (resource.Object, error) {
|
||||
return nil, k8sErrs.NewAlreadyExists(schema.GroupResource{}, obj.GetName())
|
||||
},
|
||||
updateFunc: func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.UpdateOptions) (resource.Object, error) {
|
||||
return nil, errors.New("update error")
|
||||
},
|
||||
expectedErr: errors.New("update error"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
r := &Runner{
|
||||
checkRegistry: &mockCheckRegistry{checks: tt.checks},
|
||||
client: &mockClient{
|
||||
createFunc: tt.createFunc,
|
||||
updateFunc: tt.updateFunc,
|
||||
},
|
||||
}
|
||||
err := r.Run(context.Background())
|
||||
if err != nil {
|
||||
if tt.expectedErr == nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
} else if err.Error() != tt.expectedErr.Error() {
|
||||
t.Errorf("expected error: %v, got: %v", tt.expectedErr, err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type mockCheckRegistry struct {
|
||||
checks []checks.Check
|
||||
}
|
||||
|
||||
func (m *mockCheckRegistry) Checks() []checks.Check {
|
||||
return m.checks
|
||||
}
|
||||
|
||||
type mockCheck struct {
|
||||
checks.Check
|
||||
|
||||
id string
|
||||
steps []checks.Step
|
||||
}
|
||||
|
||||
func (m *mockCheck) ID() string {
|
||||
return m.id
|
||||
}
|
||||
|
||||
func (m *mockCheck) Steps() []checks.Step {
|
||||
return m.steps
|
||||
}
|
||||
|
||||
type mockStep struct {
|
||||
checks.Step
|
||||
|
||||
id string
|
||||
title string
|
||||
description string
|
||||
}
|
||||
|
||||
func (m *mockStep) ID() string {
|
||||
return m.id
|
||||
}
|
||||
|
||||
func (m *mockStep) Title() string {
|
||||
return m.title
|
||||
}
|
||||
|
||||
func (m *mockStep) Description() string {
|
||||
return m.description
|
||||
}
|
||||
|
||||
type mockClient struct {
|
||||
resource.Client
|
||||
|
||||
createFunc func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.CreateOptions) (resource.Object, error)
|
||||
updateFunc func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.UpdateOptions) (resource.Object, error)
|
||||
}
|
||||
|
||||
func (m *mockClient) Create(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.CreateOptions) (resource.Object, error) {
|
||||
return m.createFunc(ctx, id, obj, opts)
|
||||
}
|
||||
|
||||
func (m *mockClient) Update(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.UpdateOptions) (resource.Object, error) {
|
||||
return m.updateFunc(ctx, id, obj, opts)
|
||||
}
|
||||
143
apps/advisor/pkg/app/utils.go
Normal file
143
apps/advisor/pkg/app/utils.go
Normal file
@@ -0,0 +1,143 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
claims "github.com/grafana/authlib/types"
|
||||
"github.com/grafana/grafana-app-sdk/resource"
|
||||
advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/app/checks"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
)
|
||||
|
||||
func getCheck(obj resource.Object, checkMap map[string]checks.Check) (checks.Check, error) {
|
||||
labels := obj.GetLabels()
|
||||
objTypeLabel, ok := labels[checks.TypeLabel]
|
||||
if !ok {
|
||||
return nil, errors.New("missing check type as label")
|
||||
}
|
||||
c, ok := checkMap[objTypeLabel]
|
||||
if !ok {
|
||||
supportedTypes := ""
|
||||
for k := range checkMap {
|
||||
supportedTypes += k + ", "
|
||||
}
|
||||
return nil, fmt.Errorf("unknown check type %s. Supported types are: %s", objTypeLabel, supportedTypes)
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func getStatusAnnotation(obj resource.Object) string {
|
||||
return obj.GetAnnotations()[checks.StatusAnnotation]
|
||||
}
|
||||
|
||||
func setStatusAnnotation(ctx context.Context, client resource.Client, obj resource.Object, status string) error {
|
||||
annotations := obj.GetAnnotations()
|
||||
annotations[checks.StatusAnnotation] = status
|
||||
return client.PatchInto(ctx, obj.GetStaticMetadata().Identifier(), resource.PatchRequest{
|
||||
Operations: []resource.PatchOperation{{
|
||||
Operation: resource.PatchOpAdd,
|
||||
Path: "/metadata/annotations",
|
||||
Value: annotations,
|
||||
}},
|
||||
}, resource.PatchOptions{}, obj)
|
||||
}
|
||||
|
||||
func processCheck(ctx context.Context, client resource.Client, obj resource.Object, check checks.Check) error {
|
||||
status := getStatusAnnotation(obj)
|
||||
if status != "" {
|
||||
// Check already processed
|
||||
return nil
|
||||
}
|
||||
c, ok := obj.(*advisorv0alpha1.Check)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid object type")
|
||||
}
|
||||
// Populate ctx with the user that created the check
|
||||
meta, err := utils.MetaAccessor(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
createdBy := meta.GetCreatedBy()
|
||||
typ, uid, err := claims.ParseTypeID(createdBy)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx = identity.WithRequester(ctx, &user.SignedInUser{
|
||||
UserUID: uid,
|
||||
FallbackType: typ,
|
||||
})
|
||||
// Get the items to check
|
||||
items, err := check.Items(ctx)
|
||||
if err != nil {
|
||||
setErr := setStatusAnnotation(ctx, client, obj, "error")
|
||||
if setErr != nil {
|
||||
return setErr
|
||||
}
|
||||
return fmt.Errorf("error initializing check: %w", err)
|
||||
}
|
||||
// Run the steps
|
||||
steps := check.Steps()
|
||||
failures, err := runStepsInParallel(ctx, &c.Spec, steps, items)
|
||||
if err != nil {
|
||||
setErr := setStatusAnnotation(ctx, client, obj, "error")
|
||||
if setErr != nil {
|
||||
return setErr
|
||||
}
|
||||
return fmt.Errorf("error running steps: %w", err)
|
||||
}
|
||||
|
||||
report := &advisorv0alpha1.CheckV0alpha1StatusReport{
|
||||
Failures: failures,
|
||||
Count: int64(len(items)),
|
||||
}
|
||||
err = setStatusAnnotation(ctx, client, obj, "processed")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return client.PatchInto(ctx, obj.GetStaticMetadata().Identifier(), resource.PatchRequest{
|
||||
Operations: []resource.PatchOperation{{
|
||||
Operation: resource.PatchOpAdd,
|
||||
Path: "/status/report",
|
||||
Value: *report,
|
||||
}},
|
||||
}, resource.PatchOptions{}, obj)
|
||||
}
|
||||
|
||||
func runStepsInParallel(ctx context.Context, spec *advisorv0alpha1.CheckSpec, steps []checks.Step, items []any) ([]advisorv0alpha1.CheckReportFailure, error) {
|
||||
reportFailures := []advisorv0alpha1.CheckReportFailure{}
|
||||
var internalErr error
|
||||
var wg sync.WaitGroup
|
||||
var mu sync.Mutex
|
||||
// Avoid too many concurrent requests
|
||||
limit := make(chan struct{}, 10)
|
||||
|
||||
for _, step := range steps {
|
||||
for _, item := range items {
|
||||
wg.Add(1)
|
||||
limit <- struct{}{}
|
||||
go func(step checks.Step, item any) {
|
||||
defer wg.Done()
|
||||
defer func() { <-limit }()
|
||||
stepErr, err := step.Run(ctx, spec, item)
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
if err != nil {
|
||||
internalErr = fmt.Errorf("error running step %s: %w", step.ID(), err)
|
||||
return
|
||||
}
|
||||
if stepErr != nil {
|
||||
reportFailures = append(reportFailures, *stepErr)
|
||||
}
|
||||
}(step, item)
|
||||
}
|
||||
}
|
||||
wg.Wait()
|
||||
return reportFailures, internalErr
|
||||
}
|
||||
196
apps/advisor/pkg/app/utils_test.go
Normal file
196
apps/advisor/pkg/app/utils_test.go
Normal file
@@ -0,0 +1,196 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana-app-sdk/resource"
|
||||
advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/app/checks"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGetCheck(t *testing.T) {
|
||||
obj := &advisorv0alpha1.Check{}
|
||||
obj.SetLabels(map[string]string{checks.TypeLabel: "testType"})
|
||||
|
||||
checkMap := map[string]checks.Check{
|
||||
"testType": &mockCheck{},
|
||||
}
|
||||
|
||||
check, err := getCheck(obj, checkMap)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, check)
|
||||
}
|
||||
|
||||
func TestGetCheck_MissingLabel(t *testing.T) {
|
||||
obj := &advisorv0alpha1.Check{}
|
||||
checkMap := map[string]checks.Check{}
|
||||
|
||||
_, err := getCheck(obj, checkMap)
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "missing check type as label", err.Error())
|
||||
}
|
||||
|
||||
func TestGetCheck_UnknownType(t *testing.T) {
|
||||
obj := &advisorv0alpha1.Check{}
|
||||
obj.SetLabels(map[string]string{checks.TypeLabel: "unknownType"})
|
||||
|
||||
checkMap := map[string]checks.Check{
|
||||
"testType": &mockCheck{},
|
||||
}
|
||||
|
||||
_, err := getCheck(obj, checkMap)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "unknown check type unknownType")
|
||||
}
|
||||
|
||||
func TestSetStatusAnnotation(t *testing.T) {
|
||||
obj := &advisorv0alpha1.Check{}
|
||||
obj.SetAnnotations(map[string]string{})
|
||||
client := &mockClient{}
|
||||
ctx := context.TODO()
|
||||
|
||||
err := setStatusAnnotation(ctx, client, obj, "processed")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "processed", obj.GetAnnotations()[checks.StatusAnnotation])
|
||||
}
|
||||
|
||||
func TestProcessCheck(t *testing.T) {
|
||||
obj := &advisorv0alpha1.Check{}
|
||||
obj.SetAnnotations(map[string]string{})
|
||||
meta, err := utils.MetaAccessor(obj)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
meta.SetCreatedBy("user:1")
|
||||
client := &mockClient{}
|
||||
ctx := context.TODO()
|
||||
check := &mockCheck{
|
||||
items: []any{"item"},
|
||||
}
|
||||
|
||||
err = processCheck(ctx, client, obj, check)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "processed", obj.GetAnnotations()[checks.StatusAnnotation])
|
||||
}
|
||||
|
||||
func TestProcessMultipleCheckItems(t *testing.T) {
|
||||
obj := &advisorv0alpha1.Check{}
|
||||
obj.SetAnnotations(map[string]string{})
|
||||
meta, err := utils.MetaAccessor(obj)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
meta.SetCreatedBy("user:1")
|
||||
client := &mockClient{}
|
||||
ctx := context.TODO()
|
||||
items := make([]any, 100)
|
||||
for i := range items {
|
||||
if i%2 == 0 {
|
||||
items[i] = fmt.Sprintf("item-%d", i)
|
||||
} else {
|
||||
items[i] = errors.New("error")
|
||||
}
|
||||
}
|
||||
check := &mockCheck{
|
||||
items: items,
|
||||
}
|
||||
|
||||
err = processCheck(ctx, client, obj, check)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "processed", obj.GetAnnotations()[checks.StatusAnnotation])
|
||||
r := client.lastValue.(advisorv0alpha1.CheckV0alpha1StatusReport)
|
||||
assert.Equal(t, r.Count, int64(100))
|
||||
assert.Len(t, r.Failures, 50)
|
||||
}
|
||||
|
||||
func TestProcessCheck_AlreadyProcessed(t *testing.T) {
|
||||
obj := &advisorv0alpha1.Check{}
|
||||
obj.SetAnnotations(map[string]string{checks.StatusAnnotation: "processed"})
|
||||
client := &mockClient{}
|
||||
ctx := context.TODO()
|
||||
check := &mockCheck{}
|
||||
|
||||
err := processCheck(ctx, client, obj, check)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestProcessCheck_RunError(t *testing.T) {
|
||||
obj := &advisorv0alpha1.Check{}
|
||||
obj.SetAnnotations(map[string]string{})
|
||||
meta, err := utils.MetaAccessor(obj)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
meta.SetCreatedBy("user:1")
|
||||
client := &mockClient{}
|
||||
ctx := context.TODO()
|
||||
|
||||
check := &mockCheck{
|
||||
items: []any{"item"},
|
||||
err: errors.New("run error"),
|
||||
}
|
||||
|
||||
err = processCheck(ctx, client, obj, check)
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "error", obj.GetAnnotations()[checks.StatusAnnotation])
|
||||
}
|
||||
|
||||
type mockClient struct {
|
||||
resource.Client
|
||||
lastValue any
|
||||
}
|
||||
|
||||
func (m *mockClient) PatchInto(ctx context.Context, id resource.Identifier, req resource.PatchRequest, opts resource.PatchOptions, obj resource.Object) error {
|
||||
m.lastValue = req.Operations[0].Value
|
||||
return nil
|
||||
}
|
||||
|
||||
type mockCheck struct {
|
||||
err error
|
||||
items []any
|
||||
}
|
||||
|
||||
func (m *mockCheck) ID() string {
|
||||
return "mock"
|
||||
}
|
||||
|
||||
func (m *mockCheck) Items(ctx context.Context) ([]any, error) {
|
||||
return m.items, nil
|
||||
}
|
||||
|
||||
func (m *mockCheck) Steps() []checks.Step {
|
||||
return []checks.Step{
|
||||
&mockStep{err: m.err},
|
||||
}
|
||||
}
|
||||
|
||||
type mockStep struct {
|
||||
err error
|
||||
}
|
||||
|
||||
func (m *mockStep) Run(ctx context.Context, obj *advisorv0alpha1.CheckSpec, items any) (*advisorv0alpha1.CheckReportFailure, error) {
|
||||
if m.err != nil {
|
||||
return nil, m.err
|
||||
}
|
||||
if _, ok := items.(error); ok {
|
||||
return &advisorv0alpha1.CheckReportFailure{}, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *mockStep) Title() string {
|
||||
return "mock"
|
||||
}
|
||||
|
||||
func (m *mockStep) Description() string {
|
||||
return "mock"
|
||||
}
|
||||
|
||||
func (m *mockStep) ID() string {
|
||||
return "mock"
|
||||
}
|
||||
7
apps/advisor/plugin/README.md
Normal file
7
apps/advisor/plugin/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
This folder contains the automatically generated types for the frontend that are used in the app plugin.
|
||||
|
||||
To update the types:
|
||||
|
||||
1. Make any necessary changes in the `kinds` directory
|
||||
2. Run `make generate`
|
||||
3. Copy the `plugin` directory to the frontend app: https://github.com/grafana/grafana-advisor-app/tree/main/src/plugin
|
||||
@@ -1,14 +1,14 @@
|
||||
module github.com/grafana/grafana/apps/alerting/notifications
|
||||
|
||||
go 1.23.4
|
||||
go 1.23.5
|
||||
|
||||
replace github.com/grafana/grafana => ../../..
|
||||
|
||||
require (
|
||||
github.com/grafana/grafana v0.0.0-00010101000000-000000000000
|
||||
github.com/grafana/grafana-app-sdk v0.23.1
|
||||
k8s.io/apimachinery v0.32.0
|
||||
k8s.io/apiserver v0.32.0
|
||||
github.com/grafana/grafana v11.4.0-00010101000000-000000000000+incompatible
|
||||
github.com/grafana/grafana-app-sdk v0.31.0
|
||||
k8s.io/apimachinery v0.32.1
|
||||
k8s.io/apiserver v0.32.1
|
||||
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f
|
||||
)
|
||||
|
||||
@@ -36,9 +36,9 @@ require (
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240821155123-6891eb1d35da // indirect
|
||||
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250121113133-e747350fee2d // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jmespath-community/go-jmespath v1.1.1 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
@@ -52,7 +52,7 @@ require (
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/prometheus/client_golang v1.20.5 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.61.0 // indirect
|
||||
github.com/prometheus/common v0.62.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/spf13/cobra v1.8.1 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
@@ -61,35 +61,35 @@ require (
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.16 // indirect
|
||||
go.etcd.io/etcd/client/v3 v3.5.16 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect
|
||||
go.opentelemetry.io/otel v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.33.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.4.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 // indirect
|
||||
go.opentelemetry.io/otel v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.34.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/crypto v0.32.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
|
||||
golang.org/x/net v0.34.0 // indirect
|
||||
golang.org/x/oauth2 v0.25.0 // indirect
|
||||
golang.org/x/sys v0.29.0 // indirect
|
||||
golang.org/x/oauth2 v0.26.0 // indirect
|
||||
golang.org/x/sys v0.30.0 // indirect
|
||||
golang.org/x/term v0.28.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
golang.org/x/time v0.9.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d // indirect
|
||||
google.golang.org/grpc v1.69.2 // indirect
|
||||
google.golang.org/protobuf v1.36.1 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect
|
||||
google.golang.org/grpc v1.70.0 // indirect
|
||||
google.golang.org/protobuf v1.36.4 // indirect
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/api v0.32.0 // indirect
|
||||
k8s.io/client-go v0.32.0 // indirect
|
||||
k8s.io/component-base v0.32.0 // indirect
|
||||
k8s.io/api v0.32.1 // indirect
|
||||
k8s.io/client-go v0.32.1 // indirect
|
||||
k8s.io/component-base v0.32.1 // indirect
|
||||
k8s.io/klog/v2 v2.130.1 // indirect
|
||||
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0 // indirect
|
||||
|
||||
@@ -71,18 +71,18 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grafana/grafana-app-sdk v0.23.1 h1:BRpUG0bA0oVxjthkmO2thuJBo3nbjaRSSmZJHw+mA8I=
|
||||
github.com/grafana/grafana-app-sdk v0.23.1/go.mod h1:KzgPnTJfMeckGmMctv6CJb8Jr/o/5rwARDyjXoeR0Fc=
|
||||
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240821155123-6891eb1d35da h1:2E3c/I3ayAy4Z1GwIPqXNZcpUccRapE1aBXA1ho4g7o=
|
||||
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240821155123-6891eb1d35da/go.mod h1:p09fvU5ujNL/Ig8HB7g4f+S0zyYbQq3x/f0jA4ujVOM=
|
||||
github.com/grafana/grafana-app-sdk v0.31.0 h1:/mFCcx+YqG8cWAi9hePDJQxIdtXDClDIDRgZwHkksFk=
|
||||
github.com/grafana/grafana-app-sdk v0.31.0/go.mod h1:Xw00NL7qpRLo5r3Gn48Bl1Xn2n4eUDI5pYf/wMufKWs=
|
||||
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250121113133-e747350fee2d h1:0WJ4uZ3gtbX7S5RGMarA+0TccmB7qEPhhNm34NcfBzs=
|
||||
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250121113133-e747350fee2d/go.mod h1:PNmbi49lVrv2b2I8pdu46dTs2728lKEbnVuQD8I5MnM=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 h1:uGoIog/wiQHI9GAxXO5TJbT0wWKH3O9HhOJW1F9c3fY=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340/go.mod h1:3bDW6wMZJB7tiONtC/1Xpicra6Wp5GgbTbQWCbI5fkc=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 h1:TmHmbvxPmaegwhDubVz0lICL0J5Ka2vwTzhoePEXsGE=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0/go.mod h1:qztMSjm835F2bXf+5HKAPIS5qsmQDqZna/PgVt4rWtI=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 h1:VNqngBF40hVlDloBruUehVYC3ArSgIyScOAyMRqBxRg=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1/go.mod h1:RBRO7fro65R6tjKzYgLAFo0t1QEXY1Dp+i/bvpRiqiQ=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/jmespath-community/go-jmespath v1.1.1 h1:bFikPhsi/FdmlZhVgSCd2jj1e7G/rw+zyQfyg5UF+L4=
|
||||
@@ -130,8 +130,8 @@ github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.61.0 h1:3gv/GThfX0cV2lpO7gkTUwZru38mxevy90Bj8YFSRQQ=
|
||||
github.com/prometheus/common v0.61.0/go.mod h1:zr29OCN/2BsJRaFwG8QOBr41D6kkchKbpeNH7pAjb/s=
|
||||
github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
|
||||
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
|
||||
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||
@@ -178,26 +178,26 @@ go.etcd.io/etcd/server/v3 v3.5.16 h1:d0/SAdJ3vVsZvF8IFVb1k8zqMZ+heGcNfft71ul9GWE
|
||||
go.etcd.io/etcd/server/v3 v3.5.16/go.mod h1:ynhyZZpdDp1Gq49jkUg5mfkDWZwXnn3eIqCqtJnrD/s=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 h1:PS8wXpbyaDJQ2VDHHncMe9Vct0Zn1fEjpsjrLxGJoSc=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0/go.mod h1:HDBUsEjOuRC0EzKZ1bSaRGZWUBAzo+MhAcUUORSr4D0=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 h1:yd02MEjBdJkG3uabWP9apV+OuWRIXGDuJEUJbOHmCFU=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q=
|
||||
go.opentelemetry.io/otel v1.33.0 h1:/FerN9bax5LoK51X/sI0SVYrjSE0/yUL7DpxW4K3FWw=
|
||||
go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 h1:Vh5HayB/0HHfOQA7Ctx69E/Y/DcQSMPpKANYVMQ7fBA=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0/go.mod h1:cpgtDBaqD/6ok/UG0jT15/uKjAY8mRA53diogHBg3UI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 h1:5pojmb1U1AogINhN3SurB+zm/nIcusopeBNp42f45QM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0/go.mod h1:57gTHJSE5S1tqg+EKsLPlTWhpHMsWlVmer+LA926XiA=
|
||||
go.opentelemetry.io/otel/metric v1.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ=
|
||||
go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M=
|
||||
go.opentelemetry.io/otel/sdk v1.33.0 h1:iax7M131HuAm9QkZotNHEfstof92xM+N8sr3uHXc2IM=
|
||||
go.opentelemetry.io/otel/sdk v1.33.0/go.mod h1:A1Q5oi7/9XaMlIWzPSxLRWOI8nG3FnzHJNbiENQuihM=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8=
|
||||
go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s=
|
||||
go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck=
|
||||
go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg=
|
||||
go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 h1:rgMkmiGfix9vFJDcDi1PK8WEQP4FLQwLDfhp5ZLpFeE=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0/go.mod h1:ijPqXp5P6IRRByFVVg9DY8P5HkxkHE5ARIa+86aXPf4=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I=
|
||||
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
|
||||
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE=
|
||||
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
|
||||
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
|
||||
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
|
||||
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
@@ -226,8 +226,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
|
||||
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
|
||||
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70=
|
||||
golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE=
|
||||
golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -237,8 +237,8 @@ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
|
||||
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -262,15 +262,15 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38 h1:Q3nlH8iSQSRUwOskjbcSMcF2jiYMNiQYZ0c2KEJLKKU=
|
||||
google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38/go.mod h1:xBI+tzfqGGN2JBeSebfKXFSdBpWVQ7sLW40PTupVRm4=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484 h1:ChAdCYNQFDk5fYvFZMywKLIijG7TC2m1C2CMEu11G3o=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484/go.mod h1:KRUmxRI4JmbpAm8gcZM4Jsffi859fo5LQjILwuqj9z8=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d h1:xJJRGY7TJcvIlpSrN3K6LAWgNFUILlO+OMAqtg9aqnw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d/go.mod h1:3ENsm/5D1mzDyhpzeRi1NR784I0BcofWBoSc5QqqMK4=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f h1:gap6+3Gk41EItBuyi4XX/bp4oqJ3UwuIMl25yGinuAA=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:Ic02D47M+zbarjYYUlK57y316f2MoN0gjAwI3f2S95o=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50=
|
||||
google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.69.2 h1:U3S9QEtbXC0bYNvRtcoklF3xGtLViumSYxWykJS+7AU=
|
||||
google.golang.org/grpc v1.69.2/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4=
|
||||
google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk=
|
||||
google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
|
||||
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
|
||||
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
|
||||
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
@@ -283,16 +283,16 @@ gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYs
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
k8s.io/api v0.32.0 h1:OL9JpbvAU5ny9ga2fb24X8H6xQlVp+aJMFlgtQjR9CE=
|
||||
k8s.io/api v0.32.0/go.mod h1:4LEwHZEf6Q/cG96F3dqR965sYOfmPM7rq81BLgsE0p0=
|
||||
k8s.io/apimachinery v0.32.0 h1:cFSE7N3rmEEtv4ei5X6DaJPHHX0C+upp+v5lVPiEwpg=
|
||||
k8s.io/apimachinery v0.32.0/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
|
||||
k8s.io/apiserver v0.32.0 h1:VJ89ZvQZ8p1sLeiWdRJpRD6oLozNZD2+qVSLi+ft5Qs=
|
||||
k8s.io/apiserver v0.32.0/go.mod h1:HFh+dM1/BE/Hm4bS4nTXHVfN6Z6tFIZPi649n83b4Ag=
|
||||
k8s.io/client-go v0.32.0 h1:DimtMcnN/JIKZcrSrstiwvvZvLjG0aSxy8PxN8IChp8=
|
||||
k8s.io/client-go v0.32.0/go.mod h1:boDWvdM1Drk4NJj/VddSLnx59X3OPgwrOo0vGbtq9+8=
|
||||
k8s.io/component-base v0.32.0 h1:d6cWHZkCiiep41ObYQS6IcgzOUQUNpywm39KVYaUqzU=
|
||||
k8s.io/component-base v0.32.0/go.mod h1:JLG2W5TUxUu5uDyKiH2R/7NnxJo1HlPoRIIbVLkK5eM=
|
||||
k8s.io/api v0.32.1 h1:f562zw9cy+GvXzXf0CKlVQ7yHJVYzLfL6JAS4kOAaOc=
|
||||
k8s.io/api v0.32.1/go.mod h1:/Yi/BqkuueW1BgpoePYBRdDYfjPF5sgTr5+YqDZra5k=
|
||||
k8s.io/apimachinery v0.32.1 h1:683ENpaCBjma4CYqsmZyhEzrGz6cjn1MY/X2jB2hkZs=
|
||||
k8s.io/apimachinery v0.32.1/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
|
||||
k8s.io/apiserver v0.32.1 h1:oo0OozRos66WFq87Zc5tclUX2r0mymoVHRq8JmR7Aak=
|
||||
k8s.io/apiserver v0.32.1/go.mod h1:UcB9tWjBY7aryeI5zAgzVJB/6k7E97bkr1RgqDz0jPw=
|
||||
k8s.io/client-go v0.32.1 h1:otM0AxdhdBIaQh7l1Q0jQpmo7WOFIk5FFa4bg6YMdUU=
|
||||
k8s.io/client-go v0.32.1/go.mod h1:aTTKZY7MdxUaJ/KiUs8D+GssR9zJZi77ZqtzcGXIiDg=
|
||||
k8s.io/component-base v0.32.1 h1:/5IfJ0dHIKBWysGV0yKTFfacZ5yNV1sulPh3ilJjRZk=
|
||||
k8s.io/component-base v0.32.1/go.mod h1:j1iMMHi/sqAHeG5z+O9BFNCF698a1u0186zkjMZQ28w=
|
||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y=
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
.PHONY: generate
|
||||
generate:
|
||||
@grafana-app-sdk generate -g ./pkg/apis --kindgrouping=group --postprocess --crdencoding none
|
||||
@@ -1,2 +0,0 @@
|
||||
module: "github.com/grafana/grafana/apps/investigation/kinds"
|
||||
language: version: "v0.8.2"
|
||||
@@ -1,96 +0,0 @@
|
||||
package kinds
|
||||
|
||||
// This is our Investigation definition, which contains metadata about the kind, and the kind's schema
|
||||
investigation: {
|
||||
group: "investigation"
|
||||
kind: "Investigation"
|
||||
pluralName: "Investigations"
|
||||
scope: "Namespaced"
|
||||
|
||||
apiResource: {
|
||||
groupOverride: "investigation.grafana.app"
|
||||
}
|
||||
|
||||
codegen: {
|
||||
frontend: false
|
||||
backend: true
|
||||
}
|
||||
|
||||
current: "v1alpha1"
|
||||
versions: {
|
||||
"v1alpha1": {
|
||||
version: "v1alpha1"
|
||||
schema: {
|
||||
// spec is the schema of our resource. The spec should include all the user-ediable information for the kind.
|
||||
spec: #InvestigationSpec
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#InvestigationSpec: {
|
||||
title: string
|
||||
status: "open" | "closed"
|
||||
items: [...#InvestigationItem]
|
||||
}
|
||||
|
||||
// InvestigationItem is an item in an investigation.
|
||||
#InvestigationItem: {
|
||||
id: string
|
||||
title: string
|
||||
// type is the type of the item "timeseries", "heatmap", "log-table" (not an enum to allow for future extensions).
|
||||
type: string
|
||||
// url is the URL to the item.
|
||||
url: string
|
||||
// origin is where the item was created from.
|
||||
origin: string // "explore-metrics", "explore-logs", "explore-traces" (not an enum to allow for future extensions)
|
||||
// iconPath (optional) is the path to the icon for the item.
|
||||
iconPath?: string
|
||||
// timeRange (optional) is the time range of the item.
|
||||
timeRange: #AbsoluteTimeRange
|
||||
// note (optional) is a comment on the item.
|
||||
note?: [...#Comment]
|
||||
// queryType is the type of the query used to generate this item.
|
||||
queryType: "logs" | "metrics"
|
||||
// dataQuery contains the query used to generate this item.
|
||||
dataQuery: #DataQueryLogs | #DataQueryMetrics
|
||||
}
|
||||
|
||||
// DataQueryLogs is a data query for logs.
|
||||
#DataQueryLogs: {
|
||||
// refId is the reference ID of the query.
|
||||
refId: string
|
||||
// datasource is the datasource of the query.
|
||||
datasource: #DatasourceRef
|
||||
// expr is the expression of the query.
|
||||
expr: string
|
||||
// maxLines (optional) is used to limit the number of log rows returned.
|
||||
maxLines?: int64
|
||||
}
|
||||
|
||||
// DataQueryMetrics is a data query for metrics.
|
||||
#DataQueryMetrics: {
|
||||
refId: string
|
||||
datasource: #DatasourceRef
|
||||
expr: string
|
||||
}
|
||||
|
||||
// Comment is a comment on an investigation item.
|
||||
#Comment: {
|
||||
authorUserID: string
|
||||
bodyMarkdown: string
|
||||
}
|
||||
|
||||
// DatasourceRef is a reference to a datasource.
|
||||
#DatasourceRef: {
|
||||
uid: string
|
||||
type: string
|
||||
apiVersion: string
|
||||
name: string
|
||||
}
|
||||
|
||||
// AbsoluteTimeRange is a time range specified by absolute timestamps.
|
||||
#AbsoluteTimeRange: {
|
||||
from: number
|
||||
to: number
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// InvestigationMetadata defines model for InvestigationMetadata.
|
||||
type InvestigationMetadata struct {
|
||||
CreatedBy string `json:"createdBy"`
|
||||
CreationTimestamp time.Time `json:"creationTimestamp"`
|
||||
DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty"`
|
||||
Finalizers []string `json:"finalizers"`
|
||||
Generation int64 `json:"generation"`
|
||||
Labels map[string]string `json:"labels"`
|
||||
ResourceVersion string `json:"resourceVersion"`
|
||||
Uid string `json:"uid"`
|
||||
UpdateTimestamp time.Time `json:"updateTimestamp"`
|
||||
UpdatedBy string `json:"updatedBy"`
|
||||
}
|
||||
|
||||
// _kubeObjectMetadata is metadata found in a kubernetes object's metadata field.
|
||||
// It is not exhaustive and only includes fields which may be relevant to a kind's implementation,
|
||||
// As it is also intended to be generic enough to function with any API Server.
|
||||
type InvestigationKubeObjectMetadata struct {
|
||||
CreationTimestamp time.Time `json:"creationTimestamp"`
|
||||
DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty"`
|
||||
Finalizers []string `json:"finalizers"`
|
||||
Generation int64 `json:"generation"`
|
||||
Labels map[string]string `json:"labels"`
|
||||
ResourceVersion string `json:"resourceVersion"`
|
||||
Uid string `json:"uid"`
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
package v1alpha1
|
||||
|
||||
// Defines values for InvestigationInvestigationItemQueryType.
|
||||
const (
|
||||
InvestigationInvestigationItemQueryTypeLogs InvestigationInvestigationItemQueryType = "logs"
|
||||
InvestigationInvestigationItemQueryTypeMetrics InvestigationInvestigationItemQueryType = "metrics"
|
||||
)
|
||||
|
||||
// Defines values for InvestigationSpecStatus.
|
||||
const (
|
||||
InvestigationSpecStatusClosed InvestigationSpecStatus = "closed"
|
||||
InvestigationSpecStatusOpen InvestigationSpecStatus = "open"
|
||||
)
|
||||
|
||||
// AbsoluteTimeRange is a time range specified by absolute timestamps.
|
||||
// +k8s:openapi-gen=true
|
||||
type InvestigationAbsoluteTimeRange struct {
|
||||
From float32 `json:"from"`
|
||||
To float32 `json:"to"`
|
||||
}
|
||||
|
||||
// Comment is a comment on an investigation item.
|
||||
// +k8s:openapi-gen=true
|
||||
type InvestigationComment struct {
|
||||
AuthorUserID string `json:"authorUserID"`
|
||||
BodyMarkdown string `json:"bodyMarkdown"`
|
||||
}
|
||||
|
||||
// DataQueryLogs is a data query for logs.
|
||||
// +k8s:openapi-gen=true
|
||||
type InvestigationDataQueryLogs struct {
|
||||
// DatasourceRef is a reference to a datasource.
|
||||
Datasource InvestigationDatasourceRef `json:"datasource"`
|
||||
|
||||
// expr is the expression of the query.
|
||||
Expr string `json:"expr"`
|
||||
|
||||
// maxLines (optional) is used to limit the number of log rows returned.
|
||||
MaxLines *int64 `json:"maxLines,omitempty"`
|
||||
|
||||
// refId is the reference ID of the query.
|
||||
RefId string `json:"refId"`
|
||||
}
|
||||
|
||||
// DataQueryMetrics is a data query for metrics.
|
||||
// +k8s:openapi-gen=true
|
||||
type InvestigationDataQueryMetrics struct {
|
||||
// DatasourceRef is a reference to a datasource.
|
||||
Datasource InvestigationDatasourceRef `json:"datasource"`
|
||||
Expr string `json:"expr"`
|
||||
RefId string `json:"refId"`
|
||||
}
|
||||
|
||||
// DatasourceRef is a reference to a datasource.
|
||||
// +k8s:openapi-gen=true
|
||||
type InvestigationDatasourceRef struct {
|
||||
ApiVersion string `json:"apiVersion"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Uid string `json:"uid"`
|
||||
}
|
||||
|
||||
// InvestigationItem is an item in an investigation.
|
||||
// +k8s:openapi-gen=true
|
||||
type InvestigationInvestigationItem struct {
|
||||
// dataQuery contains the query used to generate this item.
|
||||
DataQuery interface{} `json:"dataQuery"`
|
||||
|
||||
// iconPath (optional) is the path to the icon for the item.
|
||||
IconPath *string `json:"iconPath,omitempty"`
|
||||
Id string `json:"id"`
|
||||
|
||||
// note (optional) is a comment on the item.
|
||||
Note []InvestigationComment `json:"note,omitempty"`
|
||||
|
||||
// origin is where the item was created from.
|
||||
Origin string `json:"origin"`
|
||||
|
||||
// queryType is the type of the query used to generate this item.
|
||||
QueryType InvestigationInvestigationItemQueryType `json:"queryType"`
|
||||
|
||||
// AbsoluteTimeRange is a time range specified by absolute timestamps.
|
||||
TimeRange InvestigationAbsoluteTimeRange `json:"timeRange"`
|
||||
Title string `json:"title"`
|
||||
|
||||
// type is the type of the item "timeseries", "heatmap", "log-table" (not an enum to allow for future extensions).
|
||||
Type string `json:"type"`
|
||||
|
||||
// url is the URL to the item.
|
||||
Url string `json:"url"`
|
||||
}
|
||||
|
||||
// InvestigationInvestigationItemQueryType queryType is the type of the query used to generate this item.
|
||||
// +k8s:openapi-gen=true
|
||||
type InvestigationInvestigationItemQueryType string
|
||||
|
||||
// InvestigationSpec defines model for InvestigationSpec.
|
||||
// +k8s:openapi-gen=true
|
||||
type InvestigationSpec struct {
|
||||
Items []InvestigationInvestigationItem `json:"items"`
|
||||
Status InvestigationSpecStatus `json:"status"`
|
||||
Title string `json:"title"`
|
||||
}
|
||||
|
||||
// InvestigationSpecStatus defines model for InvestigationSpec.Status.
|
||||
// +k8s:openapi-gen=true
|
||||
type InvestigationSpecStatus string
|
||||
@@ -1,70 +0,0 @@
|
||||
package v1alpha1
|
||||
|
||||
// Defines values for InvestigationOperatorStateState.
|
||||
const (
|
||||
InvestigationOperatorStateStateFailed InvestigationOperatorStateState = "failed"
|
||||
InvestigationOperatorStateStateInProgress InvestigationOperatorStateState = "in_progress"
|
||||
InvestigationOperatorStateStateSuccess InvestigationOperatorStateState = "success"
|
||||
)
|
||||
|
||||
// Defines values for InvestigationstatusOperatorStateState.
|
||||
const (
|
||||
InvestigationstatusOperatorStateStateFailed InvestigationstatusOperatorStateState = "failed"
|
||||
InvestigationstatusOperatorStateStateInProgress InvestigationstatusOperatorStateState = "in_progress"
|
||||
InvestigationstatusOperatorStateStateSuccess InvestigationstatusOperatorStateState = "success"
|
||||
)
|
||||
|
||||
// InvestigationOperatorState defines model for InvestigationOperatorState.
|
||||
// +k8s:openapi-gen=true
|
||||
type InvestigationOperatorState struct {
|
||||
// descriptiveState is an optional more descriptive state field which has no requirements on format
|
||||
DescriptiveState *string `json:"descriptiveState,omitempty"`
|
||||
|
||||
// details contains any extra information that is operator-specific
|
||||
Details map[string]interface{} `json:"details,omitempty"`
|
||||
|
||||
// lastEvaluation is the ResourceVersion last evaluated
|
||||
LastEvaluation string `json:"lastEvaluation"`
|
||||
|
||||
// state describes the state of the lastEvaluation.
|
||||
// It is limited to three possible states for machine evaluation.
|
||||
State InvestigationOperatorStateState `json:"state"`
|
||||
}
|
||||
|
||||
// InvestigationOperatorStateState state describes the state of the lastEvaluation.
|
||||
// It is limited to three possible states for machine evaluation.
|
||||
// +k8s:openapi-gen=true
|
||||
type InvestigationOperatorStateState string
|
||||
|
||||
// InvestigationStatus defines model for InvestigationStatus.
|
||||
// +k8s:openapi-gen=true
|
||||
type InvestigationStatus struct {
|
||||
// additionalFields is reserved for future use
|
||||
AdditionalFields map[string]interface{} `json:"additionalFields,omitempty"`
|
||||
|
||||
// operatorStates is a map of operator ID to operator state evaluations.
|
||||
// Any operator which consumes this kind SHOULD add its state evaluation information to this field.
|
||||
OperatorStates map[string]InvestigationstatusOperatorState `json:"operatorStates,omitempty"`
|
||||
}
|
||||
|
||||
// InvestigationstatusOperatorState defines model for Investigationstatus.#OperatorState.
|
||||
// +k8s:openapi-gen=true
|
||||
type InvestigationstatusOperatorState struct {
|
||||
// descriptiveState is an optional more descriptive state field which has no requirements on format
|
||||
DescriptiveState *string `json:"descriptiveState,omitempty"`
|
||||
|
||||
// details contains any extra information that is operator-specific
|
||||
Details map[string]interface{} `json:"details,omitempty"`
|
||||
|
||||
// lastEvaluation is the ResourceVersion last evaluated
|
||||
LastEvaluation string `json:"lastEvaluation"`
|
||||
|
||||
// state describes the state of the lastEvaluation.
|
||||
// It is limited to three possible states for machine evaluation.
|
||||
State InvestigationstatusOperatorStateState `json:"state"`
|
||||
}
|
||||
|
||||
// InvestigationstatusOperatorStateState state describes the state of the lastEvaluation.
|
||||
// It is limited to three possible states for machine evaluation.
|
||||
// +k8s:openapi-gen=true
|
||||
type InvestigationstatusOperatorStateState string
|
||||
@@ -1,50 +0,0 @@
|
||||
//
|
||||
// This file is generated by grafana-app-sdk
|
||||
// DO NOT EDIT
|
||||
//
|
||||
|
||||
package apis
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/grafana/grafana-app-sdk/app"
|
||||
)
|
||||
|
||||
var (
|
||||
rawSchemaInvestigationv1alpha1 = []byte(`{"spec":{"description":"spec is the schema of our resource. The spec should include all the user-ediable information for the kind.","properties":{"items":{"items":{"properties":{"dataQuery":{"description":"dataQuery contains the query used to generate this item.","oneOf":[{"allOf":[{"required":["refId","datasource","expr"]},{"not":{"anyOf":[{"required":["refId","datasource","expr"]}]}}]},{"allOf":[{"required":["refId","datasource","expr"]},{"not":{"anyOf":[{"required":["refId","datasource","expr"]}]}}]}],"properties":{"datasource":{"description":"datasource is the datasource of the query.","properties":{"apiVersion":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"},"uid":{"type":"string"}},"required":["uid","type","apiVersion","name"],"type":"object"},"expr":{"description":"expr is the expression of the query.","type":"string"},"maxLines":{"description":"maxLines (optional) is used to limit the number of log rows returned.","format":"int64","type":"integer"},"refId":{"description":"refId is the reference ID of the query.","type":"string"}},"type":"object"},"iconPath":{"description":"iconPath (optional) is the path to the icon for the item.","type":"string"},"id":{"type":"string"},"note":{"description":"note (optional) is a comment on the item.","items":{"properties":{"authorUserID":{"type":"string"},"bodyMarkdown":{"type":"string"}},"required":["authorUserID","bodyMarkdown"],"type":"object"},"type":"array"},"origin":{"description":"origin is where the item was created from.","type":"string"},"queryType":{"description":"queryType is the type of the query used to generate this item.","enum":["logs","metrics"],"type":"string"},"timeRange":{"description":"timeRange (optional) is the time range of the item.","properties":{"from":{"type":"number"},"to":{"type":"number"}},"required":["from","to"],"type":"object"},"title":{"type":"string"},"type":{"description":"type is the type of the item \"timeseries\", \"heatmap\", \"log-table\" (not an enum to allow for future extensions).","type":"string"},"url":{"description":"url is the URL to the item.","type":"string"}},"required":["id","title","type","url","origin","timeRange","queryType","dataQuery"],"type":"object"},"type":"array"},"status":{"enum":["open","closed"],"type":"string"},"title":{"type":"string"}},"required":["title","status","items"],"type":"object"},"status":{"properties":{"additionalFields":{"description":"additionalFields is reserved for future use","type":"object","x-kubernetes-preserve-unknown-fields":true},"operatorStates":{"additionalProperties":{"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"description":"details contains any extra information that is operator-specific","type":"object","x-kubernetes-preserve-unknown-fields":true},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"}},"type":"object","x-kubernetes-preserve-unknown-fields":true}}`)
|
||||
versionSchemaInvestigationv1alpha1 app.VersionSchema
|
||||
_ = json.Unmarshal(rawSchemaInvestigationv1alpha1, &versionSchemaInvestigationv1alpha1)
|
||||
)
|
||||
|
||||
var appManifestData = app.ManifestData{
|
||||
AppName: "investigation",
|
||||
Group: "investigation.grafana.app",
|
||||
Kinds: []app.ManifestKind{
|
||||
{
|
||||
Kind: "Investigation",
|
||||
Scope: "Namespaced",
|
||||
Conversion: false,
|
||||
Versions: []app.ManifestKindVersion{
|
||||
{
|
||||
Name: "v1alpha1",
|
||||
Schema: &versionSchemaInvestigationv1alpha1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func jsonToMap(j string) map[string]any {
|
||||
m := make(map[string]any)
|
||||
json.Unmarshal([]byte(j), &j)
|
||||
return m
|
||||
}
|
||||
|
||||
func LocalManifest() app.Manifest {
|
||||
return app.NewEmbeddedManifest(appManifestData)
|
||||
}
|
||||
|
||||
func RemoteManifest() app.Manifest {
|
||||
return app.NewAPIServerManifest("investigation")
|
||||
}
|
||||
3
apps/investigations/Makefile
Normal file
3
apps/investigations/Makefile
Normal file
@@ -0,0 +1,3 @@
|
||||
.PHONY: generate
|
||||
generate:
|
||||
@grafana-app-sdk generate -g ./pkg/apis --grouping=group --postprocess --defencoding=none
|
||||
152
apps/investigations/example.json
Normal file
152
apps/investigations/example.json
Normal file
@@ -0,0 +1,152 @@
|
||||
[
|
||||
{
|
||||
"id": "896312ce-65b0-4b50-ade1-e7f04fa22c66",
|
||||
"title": "Thursday morning investigation",
|
||||
"hasCustomName": false,
|
||||
"isFavorite": false,
|
||||
"collectables": [
|
||||
{
|
||||
"origin": "Explore Logs",
|
||||
"type": "timeseries",
|
||||
"queries": [
|
||||
{
|
||||
"refId": "LABEL_BREAKDOWN_VALUES",
|
||||
"queryType": "range",
|
||||
"editorMode": "code",
|
||||
"supportingQueryType": "grafana-lokiexplore-app",
|
||||
"legendFormat": "{{detected_level}}",
|
||||
"expr": "sum(count_over_time({service_name=\"web_app_1\"} | detected_level != \"\"[$__auto])) by (detected_level)"
|
||||
}
|
||||
],
|
||||
"timeRange": {
|
||||
"to": "2025-02-13T11:31:20.536Z",
|
||||
"from": "2025-02-13T11:16:20.536Z",
|
||||
"raw": {
|
||||
"from": "now-15m",
|
||||
"to": "now"
|
||||
}
|
||||
},
|
||||
"datasource": {
|
||||
"uid": "fe9k7u07b1a0wc"
|
||||
},
|
||||
"url": "http://localhost:3000/a/grafana-lokiexplore-app/explore/service/web_app_1/labels?patterns=%5B%5D&from=now-15m&to=now&var-ds=fe9k7u07b1a0wc&var-filters=service_name%7C%3D%7Cweb_app_1&var-fields=&var-levels=&var-metadata=&var-patterns=&var-lineFilterV2=&var-lineFilters=&urlColumns=%5B%5D&visualizationType=%22logs%22&displayedFields=%5B%5D&timezone=browser&var-all-fields=&var-labelBy=$__all",
|
||||
"id": "LABEL_BREAKDOWN_VALUES_detected_level",
|
||||
"title": "detected_level",
|
||||
"logoPath": "public/plugins/grafana-lokiexplore-app/img/img/logo.svg",
|
||||
"createdAt": "2025-02-13T11:31:23.637Z"
|
||||
}
|
||||
],
|
||||
"createdAt": "2025-02-13T11:31:23.636Z",
|
||||
"updatedAt": "2025-02-13T11:31:23.637Z",
|
||||
"viewMode": {
|
||||
"mode": "compact",
|
||||
"showComments": true,
|
||||
"showTooltips": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "e9cf1958-d0ed-46b7-b597-9052c7648656",
|
||||
"title": "Thursday morning investigation",
|
||||
"hasCustomName": false,
|
||||
"isFavorite": false,
|
||||
"collectables": [
|
||||
{
|
||||
"origin": "Explore Logs",
|
||||
"type": "timeseries",
|
||||
"queries": [
|
||||
{
|
||||
"refId": "LABEL_BREAKDOWN_VALUES",
|
||||
"queryType": "range",
|
||||
"editorMode": "code",
|
||||
"supportingQueryType": "grafana-lokiexplore-app",
|
||||
"legendFormat": "{{detected_level}}",
|
||||
"expr": "sum(count_over_time({service_name=\"web_app_1\"} | detected_level != \"\"[$__auto])) by (detected_level)"
|
||||
}
|
||||
],
|
||||
"timeRange": {
|
||||
"to": "2025-02-13T11:31:20.536Z",
|
||||
"from": "2025-02-13T11:16:20.536Z",
|
||||
"raw": {
|
||||
"from": "now-15m",
|
||||
"to": "now"
|
||||
}
|
||||
},
|
||||
"datasource": {
|
||||
"uid": "fe9k7u07b1a0wc"
|
||||
},
|
||||
"url": "http://localhost:3000/a/grafana-lokiexplore-app/explore/service/web_app_1/labels?patterns=%5B%5D&from=now-15m&to=now&var-ds=fe9k7u07b1a0wc&var-filters=service_name%7C%3D%7Cweb_app_1&var-fields=&var-levels=&var-metadata=&var-patterns=&var-lineFilterV2=&var-lineFilters=&urlColumns=%5B%5D&visualizationType=%22logs%22&displayedFields=%5B%5D&timezone=browser&var-all-fields=&var-labelBy=$__all",
|
||||
"id": "LABEL_BREAKDOWN_VALUES_detected_level",
|
||||
"title": "detected_level",
|
||||
"logoPath": "public/plugins/grafana-lokiexplore-app/img/img/logo.svg",
|
||||
"createdAt": "2025-02-13T11:31:23.638Z"
|
||||
},
|
||||
{
|
||||
"origin": "Explore Logs",
|
||||
"type": "timeseries",
|
||||
"queries": [
|
||||
{
|
||||
"refId": "LABEL_BREAKDOWN_VALUES",
|
||||
"queryType": "range",
|
||||
"editorMode": "code",
|
||||
"supportingQueryType": "grafana-lokiexplore-app",
|
||||
"legendFormat": "{{service_name}}",
|
||||
"expr": "sum(count_over_time({service_name=\"web_app_1\",service_name != \"\"} [$__auto])) by (service_name)"
|
||||
}
|
||||
],
|
||||
"timeRange": {
|
||||
"to": "2025-02-13T11:31:20.536Z",
|
||||
"from": "2025-02-13T11:16:20.536Z",
|
||||
"raw": {
|
||||
"from": "now-15m",
|
||||
"to": "now"
|
||||
}
|
||||
},
|
||||
"datasource": {
|
||||
"uid": "fe9k7u07b1a0wc"
|
||||
},
|
||||
"url": "http://localhost:3000/a/grafana-lokiexplore-app/explore/service/web_app_1/labels?patterns=%5B%5D&from=now-15m&to=now&var-ds=fe9k7u07b1a0wc&var-filters=service_name%7C%3D%7Cweb_app_1&var-fields=&var-levels=&var-metadata=&var-patterns=&var-lineFilterV2=&var-lineFilters=&urlColumns=%5B%5D&visualizationType=%22logs%22&displayedFields=%5B%5D&timezone=browser&var-all-fields=&var-labelBy=$__all",
|
||||
"id": "LABEL_BREAKDOWN_VALUES_service_name",
|
||||
"title": "service_name",
|
||||
"logoPath": "public/plugins/grafana-lokiexplore-app/img/img/logo.svg",
|
||||
"createdAt": "2025-02-13T11:31:41.507Z"
|
||||
},
|
||||
{
|
||||
"origin": "Explore Logs",
|
||||
"type": "timeseries",
|
||||
"queries": [
|
||||
{
|
||||
"refId": "LABEL_BREAKDOWN_VALUES",
|
||||
"queryType": "range",
|
||||
"editorMode": "code",
|
||||
"supportingQueryType": "grafana-lokiexplore-app",
|
||||
"legendFormat": "{{service}}",
|
||||
"expr": "sum(count_over_time({service_name=\"web_app_1\",service != \"\"} [$__auto])) by (service)"
|
||||
}
|
||||
],
|
||||
"timeRange": {
|
||||
"to": "2025-02-13T11:31:20.536Z",
|
||||
"from": "2025-02-13T11:16:20.536Z",
|
||||
"raw": {
|
||||
"from": "now-15m",
|
||||
"to": "now"
|
||||
}
|
||||
},
|
||||
"datasource": {
|
||||
"uid": "fe9k7u07b1a0wc"
|
||||
},
|
||||
"url": "http://localhost:3000/a/grafana-lokiexplore-app/explore/service/web_app_1/labels?patterns=%5B%5D&from=now-15m&to=now&var-ds=fe9k7u07b1a0wc&var-filters=service_name%7C%3D%7Cweb_app_1&var-fields=&var-levels=&var-metadata=&var-patterns=&var-lineFilterV2=&var-lineFilters=&urlColumns=%5B%5D&visualizationType=%22logs%22&displayedFields=%5B%5D&timezone=browser&var-all-fields=&var-labelBy=$__all",
|
||||
"id": "LABEL_BREAKDOWN_VALUES_service",
|
||||
"title": "service",
|
||||
"logoPath": "public/plugins/grafana-lokiexplore-app/img/img/logo.svg",
|
||||
"createdAt": "2025-02-13T11:31:43.698Z"
|
||||
}
|
||||
],
|
||||
"createdAt": "2025-02-13T11:31:23.637Z",
|
||||
"updatedAt": "2025-02-13T11:31:43.698Z",
|
||||
"viewMode": {
|
||||
"mode": "compact",
|
||||
"showComments": true,
|
||||
"showTooltips": false
|
||||
}
|
||||
}
|
||||
]
|
||||
86
apps/investigations/go.mod
Normal file
86
apps/investigations/go.mod
Normal file
@@ -0,0 +1,86 @@
|
||||
module github.com/grafana/grafana/apps/investigations
|
||||
|
||||
go 1.23.4
|
||||
|
||||
require (
|
||||
github.com/grafana/grafana-app-sdk v0.31.0
|
||||
k8s.io/apimachinery v0.32.1
|
||||
k8s.io/klog/v2 v2.130.1
|
||||
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
|
||||
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
|
||||
github.com/getkin/kin-openapi v0.129.0 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
||||
github.com/go-openapi/swag v0.23.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/gnostic-models v0.6.8 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/grafana/grafana-app-sdk/logging v0.30.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.17.11 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/oasdiff/yaml v0.0.0-20241210131133-6b86fb107d80 // indirect
|
||||
github.com/oasdiff/yaml3 v0.0.0-20241210130736-a94c01f36349 // indirect
|
||||
github.com/perimeterx/marshmallow v1.1.5 // indirect
|
||||
github.com/prometheus/client_golang v1.20.5 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.62.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/puzpuzpuz/xsync/v2 v2.5.1 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/otel v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.34.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
|
||||
golang.org/x/net v0.34.0 // indirect
|
||||
golang.org/x/oauth2 v0.26.0 // indirect
|
||||
golang.org/x/sync v0.11.0 // indirect
|
||||
golang.org/x/sys v0.30.0 // indirect
|
||||
golang.org/x/term v0.28.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
golang.org/x/time v0.9.0 // indirect
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect
|
||||
google.golang.org/grpc v1.70.0 // indirect
|
||||
google.golang.org/protobuf v1.36.4 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/api v0.32.1 // indirect
|
||||
k8s.io/apiextensions-apiserver v0.32.1 // indirect
|
||||
k8s.io/client-go v0.32.1 // indirect
|
||||
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.5.0 // indirect
|
||||
sigs.k8s.io/yaml v1.4.0 // indirect
|
||||
)
|
||||
228
apps/investigations/go.sum
Normal file
228
apps/investigations/go.sum
Normal file
@@ -0,0 +1,228 @@
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous=
|
||||
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
|
||||
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||
github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U=
|
||||
github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
|
||||
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
|
||||
github.com/getkin/kin-openapi v0.129.0 h1:QGYTNcmyP5X0AtFQ2Dkou9DGBJsUETeLH9rFrJXZh30=
|
||||
github.com/getkin/kin-openapi v0.129.0/go.mod h1:gmWI+b/J45xqpyK5wJmRRZse5wefA5H0RDMK46kLUtI=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
|
||||
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
|
||||
github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
|
||||
github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
|
||||
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
|
||||
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||
github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
|
||||
github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
|
||||
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg=
|
||||
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/grafana/grafana-app-sdk v0.31.0 h1:/mFCcx+YqG8cWAi9hePDJQxIdtXDClDIDRgZwHkksFk=
|
||||
github.com/grafana/grafana-app-sdk v0.31.0/go.mod h1:Xw00NL7qpRLo5r3Gn48Bl1Xn2n4eUDI5pYf/wMufKWs=
|
||||
github.com/grafana/grafana-app-sdk/logging v0.30.0 h1:K/P/bm7Cp7Di4tqIJ3EQz2+842JozQGRaz62r95ApME=
|
||||
github.com/grafana/grafana-app-sdk/logging v0.30.0/go.mod h1:xy6ZyVXl50Z3DBDLybvBPphbykPhuVNed/VNmen9DQM=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 h1:VNqngBF40hVlDloBruUehVYC3ArSgIyScOAyMRqBxRg=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1/go.mod h1:RBRO7fro65R6tjKzYgLAFo0t1QEXY1Dp+i/bvpRiqiQ=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
|
||||
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/oasdiff/yaml v0.0.0-20241210131133-6b86fb107d80 h1:nZspmSkneBbtxU9TopEAE0CY+SBJLxO8LPUlw2vG4pU=
|
||||
github.com/oasdiff/yaml v0.0.0-20241210131133-6b86fb107d80/go.mod h1:7tFDb+Y51LcDpn26GccuUgQXUk6t0CXZsivKjyimYX8=
|
||||
github.com/oasdiff/yaml3 v0.0.0-20241210130736-a94c01f36349 h1:t05Ww3DxZutOqbMN+7OIuqDwXbhl32HiZGpLy26BAPc=
|
||||
github.com/oasdiff/yaml3 v0.0.0-20241210130736-a94c01f36349/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o=
|
||||
github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM=
|
||||
github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
|
||||
github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4=
|
||||
github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
|
||||
github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s=
|
||||
github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
|
||||
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
|
||||
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
|
||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||
github.com/puzpuzpuz/xsync/v2 v2.5.1 h1:mVGYAvzDSu52+zaGyNjC+24Xw2bQi3kTr4QJ6N9pIIU=
|
||||
github.com/puzpuzpuz/xsync/v2 v2.5.1/go.mod h1:gD2H2krq/w52MfPLE+Uy64TzJDVY7lP2znR9qmR35kU=
|
||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
|
||||
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 h1:BEj3SPM81McUZHYjRS5pEgNgnmzGJ5tRpU5krWnV8Bs=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0/go.mod h1:9cKLGBDzI/F3NoHLQGm4ZrYdIHsvGt6ej6hUowxY0J4=
|
||||
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
|
||||
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
|
||||
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
|
||||
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
|
||||
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
||||
golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE=
|
||||
golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
||||
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
|
||||
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
|
||||
golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE=
|
||||
golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f h1:gap6+3Gk41EItBuyi4XX/bp4oqJ3UwuIMl25yGinuAA=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:Ic02D47M+zbarjYYUlK57y316f2MoN0gjAwI3f2S95o=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50=
|
||||
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
|
||||
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
|
||||
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
|
||||
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
k8s.io/api v0.32.1 h1:f562zw9cy+GvXzXf0CKlVQ7yHJVYzLfL6JAS4kOAaOc=
|
||||
k8s.io/api v0.32.1/go.mod h1:/Yi/BqkuueW1BgpoePYBRdDYfjPF5sgTr5+YqDZra5k=
|
||||
k8s.io/apiextensions-apiserver v0.32.1 h1:hjkALhRUeCariC8DiVmb5jj0VjIc1N0DREP32+6UXZw=
|
||||
k8s.io/apiextensions-apiserver v0.32.1/go.mod h1:sxWIGuGiYov7Io1fAS2X06NjMIk5CbRHc2StSmbaQto=
|
||||
k8s.io/apimachinery v0.32.1 h1:683ENpaCBjma4CYqsmZyhEzrGz6cjn1MY/X2jB2hkZs=
|
||||
k8s.io/apimachinery v0.32.1/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
|
||||
k8s.io/client-go v0.32.1 h1:otM0AxdhdBIaQh7l1Q0jQpmo7WOFIk5FFa4bg6YMdUU=
|
||||
k8s.io/client-go v0.32.1/go.mod h1:aTTKZY7MdxUaJ/KiUs8D+GssR9zJZi77ZqtzcGXIiDg=
|
||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y=
|
||||
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f/go.mod h1:R/HEjbvWI0qdfb8viZUeVZm0X6IZnxAydC7YU42CMw4=
|
||||
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro=
|
||||
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8=
|
||||
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.5.0 h1:nbCitCK2hfnhyiKo6uf2HxUPTCodY6Qaf85SbDIaMBk=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.5.0/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4=
|
||||
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
|
||||
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
|
||||
51
apps/investigations/kinds/collectable.cue
Normal file
51
apps/investigations/kinds/collectable.cue
Normal file
@@ -0,0 +1,51 @@
|
||||
package investigations
|
||||
|
||||
// Collectable represents an item collected during investigation
|
||||
#Collectable: {
|
||||
id: string
|
||||
createdAt: string
|
||||
|
||||
title: string
|
||||
origin: string
|
||||
type: string
|
||||
queries: [...#Query] // +listType=atomic
|
||||
timeRange: #TimeRange
|
||||
datasource: #DatasourceRef
|
||||
url: string
|
||||
logoPath?: string
|
||||
|
||||
note: string
|
||||
noteUpdatedAt: string
|
||||
}
|
||||
|
||||
#CollectableSummary: {
|
||||
id: string
|
||||
title: string
|
||||
logoPath: string
|
||||
origin: string
|
||||
}
|
||||
|
||||
// Query represents a data query
|
||||
#Query: {
|
||||
refId: string
|
||||
queryType: string
|
||||
editorMode: string
|
||||
supportingQueryType: string
|
||||
legendFormat: string
|
||||
expr: string
|
||||
}
|
||||
|
||||
// TimeRange represents a time range with both absolute and relative values
|
||||
#TimeRange: {
|
||||
from: string
|
||||
to: string
|
||||
raw: {
|
||||
from: string
|
||||
to: string
|
||||
}
|
||||
}
|
||||
|
||||
// DatasourceRef is a reference to a datasource
|
||||
#DatasourceRef: {
|
||||
uid: string
|
||||
}
|
||||
1
apps/investigations/kinds/cue.mod/module.cue
Normal file
1
apps/investigations/kinds/cue.mod/module.cue
Normal file
@@ -0,0 +1 @@
|
||||
module: "github.com/grafana/grafana/apps/investigations"
|
||||
64
apps/investigations/kinds/investigation.cue
Normal file
64
apps/investigations/kinds/investigation.cue
Normal file
@@ -0,0 +1,64 @@
|
||||
package investigations
|
||||
|
||||
// This is our Investigation definition, which contains metadata about the kind, and the kind's schema
|
||||
investigation: {
|
||||
kind: "Investigation"
|
||||
group: "investigations.grafana.app"
|
||||
apiResource: {
|
||||
groupOverride: "investigations.grafana.app"
|
||||
}
|
||||
pluralName: "Investigations"
|
||||
current: "v0alpha1"
|
||||
versions: {
|
||||
"v0alpha1": {
|
||||
codegen: {
|
||||
frontend: true
|
||||
backend: true
|
||||
options: {
|
||||
generateObjectMeta: true
|
||||
generateClient: true
|
||||
k8sLike: true
|
||||
package: "github.com/grafana/grafana/apps/investigations"
|
||||
}
|
||||
}
|
||||
schema: {
|
||||
// spec is the schema of our resource
|
||||
spec: {
|
||||
title: string
|
||||
createdByProfile: #Person
|
||||
hasCustomName: bool
|
||||
isFavorite: bool
|
||||
overviewNote: string
|
||||
overviewNoteUpdatedAt: string
|
||||
collectables: [...#Collectable] // +listType=atomic
|
||||
viewMode: #ViewMode
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Type definition for investigation summaries
|
||||
#InvestigationSummary: {
|
||||
title: string
|
||||
createdByProfile: #Person
|
||||
hasCustomName: bool
|
||||
isFavorite: bool
|
||||
overviewNote: string
|
||||
overviewNoteUpdatedAt: string
|
||||
viewMode: #ViewMode
|
||||
collectableSummaries: [...#CollectableSummary] // +listType=atomic
|
||||
}
|
||||
|
||||
// Person represents a user profile with basic information
|
||||
#Person: {
|
||||
uid: string // Unique identifier for the user
|
||||
name: string // Display name of the user
|
||||
gravatarUrl: string // URL to user's Gravatar image
|
||||
}
|
||||
|
||||
#ViewMode: {
|
||||
mode: "compact" | "full"
|
||||
showComments: bool
|
||||
showTooltips: bool
|
||||
}
|
||||
37
apps/investigations/kinds/investigationindex.cue
Normal file
37
apps/investigations/kinds/investigationindex.cue
Normal file
@@ -0,0 +1,37 @@
|
||||
package investigations
|
||||
|
||||
investigationIndex: {
|
||||
kind: "InvestigationIndex"
|
||||
group: "investigations.grafana.app"
|
||||
apiResource: {
|
||||
groupOverride: "investigations.grafana.app"
|
||||
}
|
||||
pluralName: "InvestigationIndexes"
|
||||
current: "v0alpha1"
|
||||
versions: {
|
||||
"v0alpha1": {
|
||||
codegen: {
|
||||
frontend: true
|
||||
backend: true
|
||||
options: {
|
||||
generateObjectMeta: true
|
||||
generateClient: true
|
||||
k8sLike: true
|
||||
package: "github.com/grafana/grafana/apps/investigations"
|
||||
}
|
||||
}
|
||||
schema: {
|
||||
spec: {
|
||||
// Title of the index, e.g. 'Favorites' or 'My Investigations'
|
||||
title: string
|
||||
|
||||
// The Person who owns this investigation index
|
||||
owner: #Person
|
||||
|
||||
// Array of investigation summaries
|
||||
investigationSummaries: [...#InvestigationSummary] // +listType=atomic
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
10
apps/investigations/kinds/manifest.cue
Normal file
10
apps/investigations/kinds/manifest.cue
Normal file
@@ -0,0 +1,10 @@
|
||||
package investigations
|
||||
|
||||
manifest: {
|
||||
appName: "investigations"
|
||||
groupOverride: "investigations.grafana.app"
|
||||
kinds: [
|
||||
investigation,
|
||||
investigationIndex,
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package v0alpha1
|
||||
|
||||
import "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
const (
|
||||
// Group is the API group used by all kinds in this package
|
||||
Group = "investigations.grafana.app"
|
||||
// Version is the API version used by all kinds in this package
|
||||
Version = "v0alpha1"
|
||||
)
|
||||
|
||||
var (
|
||||
// GroupVersion is a schema.GroupVersion consisting of the Group and Version constants for this package
|
||||
GroupVersion = schema.GroupVersion{
|
||||
Group: Group,
|
||||
Version: Version,
|
||||
}
|
||||
)
|
||||
@@ -2,7 +2,7 @@
|
||||
// Code generated by grafana-app-sdk. DO NOT EDIT.
|
||||
//
|
||||
|
||||
package v1alpha1
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@@ -0,0 +1,28 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
time "time"
|
||||
)
|
||||
|
||||
// metadata contains embedded CommonMetadata and can be extended with custom string fields
|
||||
// TODO: use CommonMetadata instead of redefining here; currently needs to be defined here
|
||||
// without external reference as using the CommonMetadata reference breaks thema codegen.
|
||||
type InvestigationMetadata struct {
|
||||
UpdateTimestamp time.Time `json:"updateTimestamp"`
|
||||
CreatedBy string `json:"createdBy"`
|
||||
Uid string `json:"uid"`
|
||||
CreationTimestamp time.Time `json:"creationTimestamp"`
|
||||
DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty"`
|
||||
Finalizers []string `json:"finalizers"`
|
||||
ResourceVersion string `json:"resourceVersion"`
|
||||
Generation int64 `json:"generation"`
|
||||
UpdatedBy string `json:"updatedBy"`
|
||||
Labels map[string]string `json:"labels"`
|
||||
}
|
||||
|
||||
// NewInvestigationMetadata creates a new InvestigationMetadata object.
|
||||
func NewInvestigationMetadata() *InvestigationMetadata {
|
||||
return &InvestigationMetadata{}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
// Code generated by grafana-app-sdk. DO NOT EDIT.
|
||||
//
|
||||
|
||||
package v1alpha1
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -16,10 +16,10 @@ import (
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type Investigation struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata"`
|
||||
Spec InvestigationSpec `json:"spec"`
|
||||
InvestigationStatus InvestigationStatus `json:"status"`
|
||||
metav1.TypeMeta `json:",inline" yaml:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata" yaml:"metadata"`
|
||||
Spec InvestigationSpec `json:"spec" yaml:"spec"`
|
||||
InvestigationStatus InvestigationStatus `json:"status" yaml:"status"`
|
||||
}
|
||||
|
||||
func (o *Investigation) GetSpec() any {
|
||||
@@ -224,9 +224,9 @@ var _ resource.Object = &Investigation{}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type InvestigationList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata"`
|
||||
Items []Investigation `json:"items"`
|
||||
metav1.TypeMeta `json:",inline" yaml:",inline"`
|
||||
metav1.ListMeta `json:"metadata" yaml:"metadata"`
|
||||
Items []Investigation `json:"items" yaml:"items"`
|
||||
}
|
||||
|
||||
func (o *InvestigationList) DeepCopyObject() runtime.Object {
|
||||
@@ -2,7 +2,7 @@
|
||||
// Code generated by grafana-app-sdk. DO NOT EDIT.
|
||||
//
|
||||
|
||||
package v1alpha1
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
"github.com/grafana/grafana-app-sdk/resource"
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
|
||||
// schema is unexported to prevent accidental overwrites
|
||||
var (
|
||||
schemaInvestigation = resource.NewSimpleSchema("investigation.grafana.app", "v1alpha1", &Investigation{}, &InvestigationList{}, resource.WithKind("Investigation"),
|
||||
schemaInvestigation = resource.NewSimpleSchema("investigations.grafana.app", "v0alpha1", &Investigation{}, &InvestigationList{}, resource.WithKind("Investigation"),
|
||||
resource.WithPlural("investigations"), resource.WithScope(resource.NamespacedScope))
|
||||
kindInvestigation = resource.Kind{
|
||||
Schema: schemaInvestigation,
|
||||
@@ -0,0 +1,140 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
|
||||
package v0alpha1
|
||||
|
||||
// Person represents a user profile with basic information
|
||||
// +k8s:openapi-gen=true
|
||||
type InvestigationPerson struct {
|
||||
// Unique identifier for the user
|
||||
Uid string `json:"uid"`
|
||||
// Display name of the user
|
||||
Name string `json:"name"`
|
||||
// URL to user's Gravatar image
|
||||
GravatarUrl string `json:"gravatarUrl"`
|
||||
}
|
||||
|
||||
// NewInvestigationPerson creates a new InvestigationPerson object.
|
||||
func NewInvestigationPerson() *InvestigationPerson {
|
||||
return &InvestigationPerson{}
|
||||
}
|
||||
|
||||
// Collectable represents an item collected during investigation
|
||||
// +k8s:openapi-gen=true
|
||||
type InvestigationCollectable struct {
|
||||
Id string `json:"id"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
Title string `json:"title"`
|
||||
Origin string `json:"origin"`
|
||||
Type string `json:"type"`
|
||||
// +listType=atomic
|
||||
Queries []InvestigationQuery `json:"queries"`
|
||||
TimeRange InvestigationTimeRange `json:"timeRange"`
|
||||
Datasource InvestigationDatasourceRef `json:"datasource"`
|
||||
Url string `json:"url"`
|
||||
LogoPath *string `json:"logoPath,omitempty"`
|
||||
Note string `json:"note"`
|
||||
NoteUpdatedAt string `json:"noteUpdatedAt"`
|
||||
}
|
||||
|
||||
// NewInvestigationCollectable creates a new InvestigationCollectable object.
|
||||
func NewInvestigationCollectable() *InvestigationCollectable {
|
||||
return &InvestigationCollectable{
|
||||
TimeRange: *NewInvestigationTimeRange(),
|
||||
Datasource: *NewInvestigationDatasourceRef(),
|
||||
}
|
||||
}
|
||||
|
||||
// Query represents a data query
|
||||
// +k8s:openapi-gen=true
|
||||
type InvestigationQuery struct {
|
||||
RefId string `json:"refId"`
|
||||
QueryType string `json:"queryType"`
|
||||
EditorMode string `json:"editorMode"`
|
||||
SupportingQueryType string `json:"supportingQueryType"`
|
||||
LegendFormat string `json:"legendFormat"`
|
||||
Expr string `json:"expr"`
|
||||
}
|
||||
|
||||
// NewInvestigationQuery creates a new InvestigationQuery object.
|
||||
func NewInvestigationQuery() *InvestigationQuery {
|
||||
return &InvestigationQuery{}
|
||||
}
|
||||
|
||||
// TimeRange represents a time range with both absolute and relative values
|
||||
// +k8s:openapi-gen=true
|
||||
type InvestigationTimeRange struct {
|
||||
From string `json:"from"`
|
||||
To string `json:"to"`
|
||||
Raw InvestigationV0alpha1TimeRangeRaw `json:"raw"`
|
||||
}
|
||||
|
||||
// NewInvestigationTimeRange creates a new InvestigationTimeRange object.
|
||||
func NewInvestigationTimeRange() *InvestigationTimeRange {
|
||||
return &InvestigationTimeRange{
|
||||
Raw: *NewInvestigationV0alpha1TimeRangeRaw(),
|
||||
}
|
||||
}
|
||||
|
||||
// DatasourceRef is a reference to a datasource
|
||||
// +k8s:openapi-gen=true
|
||||
type InvestigationDatasourceRef struct {
|
||||
Uid string `json:"uid"`
|
||||
}
|
||||
|
||||
// NewInvestigationDatasourceRef creates a new InvestigationDatasourceRef object.
|
||||
func NewInvestigationDatasourceRef() *InvestigationDatasourceRef {
|
||||
return &InvestigationDatasourceRef{}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type InvestigationViewMode struct {
|
||||
Mode InvestigationViewModeMode `json:"mode"`
|
||||
ShowComments bool `json:"showComments"`
|
||||
ShowTooltips bool `json:"showTooltips"`
|
||||
}
|
||||
|
||||
// NewInvestigationViewMode creates a new InvestigationViewMode object.
|
||||
func NewInvestigationViewMode() *InvestigationViewMode {
|
||||
return &InvestigationViewMode{}
|
||||
}
|
||||
|
||||
// spec is the schema of our resource
|
||||
// +k8s:openapi-gen=true
|
||||
type InvestigationSpec struct {
|
||||
Title string `json:"title"`
|
||||
CreatedByProfile InvestigationPerson `json:"createdByProfile"`
|
||||
HasCustomName bool `json:"hasCustomName"`
|
||||
IsFavorite bool `json:"isFavorite"`
|
||||
OverviewNote string `json:"overviewNote"`
|
||||
OverviewNoteUpdatedAt string `json:"overviewNoteUpdatedAt"`
|
||||
// +listType=atomic
|
||||
Collectables []InvestigationCollectable `json:"collectables"`
|
||||
ViewMode InvestigationViewMode `json:"viewMode"`
|
||||
}
|
||||
|
||||
// NewInvestigationSpec creates a new InvestigationSpec object.
|
||||
func NewInvestigationSpec() *InvestigationSpec {
|
||||
return &InvestigationSpec{
|
||||
CreatedByProfile: *NewInvestigationPerson(),
|
||||
ViewMode: *NewInvestigationViewMode(),
|
||||
}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type InvestigationV0alpha1TimeRangeRaw struct {
|
||||
From string `json:"from"`
|
||||
To string `json:"to"`
|
||||
}
|
||||
|
||||
// NewInvestigationV0alpha1TimeRangeRaw creates a new InvestigationV0alpha1TimeRangeRaw object.
|
||||
func NewInvestigationV0alpha1TimeRangeRaw() *InvestigationV0alpha1TimeRangeRaw {
|
||||
return &InvestigationV0alpha1TimeRangeRaw{}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type InvestigationViewModeMode string
|
||||
|
||||
const (
|
||||
InvestigationViewModeModeCompact InvestigationViewModeMode = "compact"
|
||||
InvestigationViewModeModeFull InvestigationViewModeMode = "full"
|
||||
)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user