Add git functions & improve grafana functions
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
2d08f75545
commit
0fb6e0b6e9
7 changed files with 579 additions and 16 deletions
29
go.mod
29
go.mod
|
@ -2,4 +2,31 @@ module git.ar21.de/yolokube/grafana-backuper
|
|||
|
||||
go 1.21.5
|
||||
|
||||
require github.com/alecthomas/kong v0.8.1
|
||||
require (
|
||||
github.com/ProtonMail/go-crypto v1.0.0
|
||||
github.com/alecthomas/kong v0.8.1
|
||||
github.com/go-git/go-billy/v5 v5.5.0
|
||||
github.com/go-git/go-git/v5 v5.11.0
|
||||
)
|
||||
|
||||
require (
|
||||
dario.cat/mergo v1.0.0 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
||||
github.com/cloudflare/circl v1.3.7 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
|
||||
github.com/emirpasic/gods v1.18.1 // indirect
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||
github.com/kevinburke/ssh_config v1.2.0 // indirect
|
||||
github.com/pjbgf/sha1cd v0.3.0 // indirect
|
||||
github.com/sergi/go-diff v1.3.1 // indirect
|
||||
github.com/skeema/knownhosts v1.2.1 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||
golang.org/x/crypto v0.19.0 // indirect
|
||||
golang.org/x/mod v0.15.0 // indirect
|
||||
golang.org/x/net v0.21.0 // indirect
|
||||
golang.org/x/sys v0.17.0 // indirect
|
||||
golang.org/x/tools v0.18.0 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
)
|
||||
|
|
145
go.sum
145
go.sum
|
@ -1,8 +1,153 @@
|
|||
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
|
||||
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
|
||||
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
|
||||
github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78=
|
||||
github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
|
||||
github.com/alecthomas/assert/v2 v2.1.0 h1:tbredtNcQnoSd3QBhQWI7QZ3XHOVkw1Moklp2ojoH/0=
|
||||
github.com/alecthomas/assert/v2 v2.1.0/go.mod h1:b/+1DI2Q6NckYi+3mXyH3wFb8qG37K/DuK80n7WefXA=
|
||||
github.com/alecthomas/kong v0.8.1 h1:acZdn3m4lLRobeh3Zi2S2EpnXTd1mOL6U7xVml+vfkY=
|
||||
github.com/alecthomas/kong v0.8.1/go.mod h1:n1iCIO2xS46oE8ZfYCNDqdR0b0wZNrXAIAqro/2132U=
|
||||
github.com/alecthomas/repr v0.1.0 h1:ENn2e1+J3k09gyj2shc0dHr/yjaWSHRlrJ4DPMevDqE=
|
||||
github.com/alecthomas/repr v0.1.0/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
|
||||
github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
|
||||
github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
|
||||
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
|
||||
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU=
|
||||
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
|
||||
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
|
||||
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
|
||||
github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
|
||||
github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4=
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
|
||||
github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
|
||||
github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
|
||||
github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4=
|
||||
github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
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/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
|
||||
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
|
||||
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
|
||||
github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
|
||||
github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
|
||||
github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
|
||||
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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
||||
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
|
||||
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ=
|
||||
github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
||||
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=
|
||||
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
||||
golang.org/x/sync v0.6.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-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||
golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
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.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
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.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ=
|
||||
golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/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/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
67
main.go
67
main.go
|
@ -4,15 +4,21 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"slices"
|
||||
|
||||
"git.ar21.de/yolokube/grafana-backuper/pkg/git"
|
||||
"git.ar21.de/yolokube/grafana-backuper/pkg/grafana"
|
||||
)
|
||||
|
||||
const (
|
||||
grafanaURL = "https://grafana.services.yolokube.de"
|
||||
grafanaAPIKey = ""
|
||||
gitRepoURL = ""
|
||||
gitRepoDirectory = ""
|
||||
grafanaURL = "https://grafana.services.yolokube.de"
|
||||
grafanaAPIKey = ""
|
||||
gitBranch = "main"
|
||||
gitRepoURL = ""
|
||||
gitUsername = ""
|
||||
gitEmail = ""
|
||||
gitPassword = ""
|
||||
privateGPGKeyFile = ""
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -22,21 +28,66 @@ func main() {
|
|||
log.Fatalf("Error creating the grafana client: %v", err)
|
||||
}
|
||||
|
||||
gitdata := git.NewPayload(privateGPGKeyFile)
|
||||
if err = gitdata.GetRepo(gitRepoURL, gitUsername, gitPassword); err != nil {
|
||||
log.Fatalf("Error cloning git repo: %v", err)
|
||||
}
|
||||
|
||||
gitdata.AddCommitter(gitUsername, gitEmail)
|
||||
|
||||
dashboards, err := client.SearchDashboards(ctx, "", false)
|
||||
if err != nil {
|
||||
log.Fatalf("Error fetching dashboards: %v", err)
|
||||
}
|
||||
|
||||
for _, dashboard := range dashboards {
|
||||
versions, err := client.GetDashboardVersionsByDashboardID(ctx, dashboard.ID)
|
||||
gitdata.UpdateDashboard(dashboard)
|
||||
|
||||
_, dashboardInfo, err := client.GetRawDashboardByUID(ctx, dashboard.UID)
|
||||
if err != nil {
|
||||
log.Fatalf("Error fetching information of dashboard %s: %v", dashboard.Title, err)
|
||||
}
|
||||
|
||||
gitdata.UpdateDashboardInfo(dashboardInfo)
|
||||
|
||||
versions, err := client.GetDashboardVersionsByDashboardUID(ctx, dashboard.UID)
|
||||
if err != nil {
|
||||
log.Fatalf("Error fetching versions for dashboard %s: %v", dashboard.Title, err)
|
||||
}
|
||||
|
||||
fmt.Println(dashboard.Title)
|
||||
fmt.Println(versions)
|
||||
slices.Reverse(versions)
|
||||
|
||||
for _, version := range versions {
|
||||
fmt.Printf("%s: %s\n", version.CreatedBy, version.Message)
|
||||
gitdata.UpdateVersion(version)
|
||||
|
||||
if gitdata.IsVersionCommitted(gitBranch) {
|
||||
fmt.Printf("%s/%s - %s: %s -> already committed\n", dashboardInfo.FolderTitle, dashboard.Title, version.CreatedBy, version.Message)
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("%s/%s - %s: %s\n", dashboardInfo.FolderTitle, dashboard.Title, version.CreatedBy, version.Message)
|
||||
|
||||
raw, info, err := client.GetRawDashboardByUIDAndVersion(ctx, dashboard.UID, version.Version)
|
||||
if err != nil {
|
||||
log.Fatalf("Error fetching dashboard %s version %d: %v", dashboard.Title, version.Version, err)
|
||||
}
|
||||
|
||||
gitdata.AddAuthor(info.CreatedBy, "")
|
||||
|
||||
output, err := grafana.ConvertRawToIndent(raw)
|
||||
if err != nil {
|
||||
log.Fatalf("Error pritty-printing dashboard %s version %d: %v", dashboard.Title, info.Version, err)
|
||||
}
|
||||
|
||||
gitdata.UpdateContent([]byte(output))
|
||||
gitdata.UpdateCommitter()
|
||||
if err = gitdata.CreateCommit(); err != nil {
|
||||
log.Fatalf("Error creating commit for dashboard %s version %d: %v", dashboard.Title, info.Version, err)
|
||||
}
|
||||
|
||||
if err = gitdata.PushToRemote(gitUsername, gitPassword); err != nil {
|
||||
log.Fatalf("Error pushing to remote repo %s: %v", gitRepoURL, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
240
pkg/git/git.go
Normal file
240
pkg/git/git.go
Normal file
|
@ -0,0 +1,240 @@
|
|||
package git
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.ar21.de/yolokube/grafana-backuper/pkg/grafana"
|
||||
"github.com/ProtonMail/go-crypto/openpgp"
|
||||
"github.com/go-git/go-billy/v5"
|
||||
"github.com/go-git/go-billy/v5/memfs"
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/go-git/go-git/v5/plumbing"
|
||||
"github.com/go-git/go-git/v5/plumbing/object"
|
||||
"github.com/go-git/go-git/v5/plumbing/transport/http"
|
||||
"github.com/go-git/go-git/v5/storage/memory"
|
||||
)
|
||||
|
||||
var (
|
||||
fs billy.Filesystem
|
||||
storer *memory.Storage
|
||||
)
|
||||
|
||||
type Payload struct {
|
||||
Author *object.Signature
|
||||
Committer *object.Signature
|
||||
Content []byte
|
||||
Dashboard grafana.FoundBoard
|
||||
DashboardInfo grafana.BoardProperties
|
||||
Directory string
|
||||
KeyFile string
|
||||
Repository *git.Repository
|
||||
Version grafana.DashboardVersion
|
||||
}
|
||||
|
||||
func NewPayload(keyFile string) *Payload {
|
||||
fs = memfs.New()
|
||||
storer = memory.NewStorage()
|
||||
|
||||
return &Payload{
|
||||
Author: nil,
|
||||
Committer: nil,
|
||||
Content: []byte{},
|
||||
Dashboard: grafana.FoundBoard{},
|
||||
DashboardInfo: grafana.BoardProperties{},
|
||||
Directory: "",
|
||||
KeyFile: keyFile,
|
||||
Repository: nil,
|
||||
Version: grafana.DashboardVersion{},
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Payload) AddAuthor(name, email string) {
|
||||
p.Author = &object.Signature{
|
||||
Name: name,
|
||||
Email: email,
|
||||
When: time.Now(),
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Payload) UpdateAuthor(timestamp time.Time) {
|
||||
p.Author.When = timestamp
|
||||
}
|
||||
|
||||
func (p *Payload) AddCommitter(name, email string) {
|
||||
p.Committer = &object.Signature{
|
||||
Name: name,
|
||||
Email: email,
|
||||
When: time.Now(),
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Payload) UpdateCommitter() {
|
||||
p.Committer.When = time.Now()
|
||||
}
|
||||
|
||||
func (p *Payload) UpdateContent(content []byte) {
|
||||
p.Content = content
|
||||
}
|
||||
|
||||
func (p *Payload) UpdateDashboard(dashboard grafana.FoundBoard) {
|
||||
p.Dashboard = dashboard
|
||||
}
|
||||
|
||||
func (p *Payload) UpdateDashboardInfo(dashboardInfo grafana.BoardProperties) {
|
||||
p.DashboardInfo = dashboardInfo
|
||||
}
|
||||
|
||||
func (p *Payload) UpdateVersion(version grafana.DashboardVersion) {
|
||||
p.Version = version
|
||||
}
|
||||
|
||||
func (p *Payload) GetRepo(repoURL, user, password string) (err error) {
|
||||
p.Repository, err = git.Clone(
|
||||
storer,
|
||||
fs,
|
||||
&git.CloneOptions{
|
||||
Auth: genAuth(user, password),
|
||||
URL: repoURL,
|
||||
Progress: os.Stdout,
|
||||
},
|
||||
)
|
||||
|
||||
p.Directory = filepath.Base(repoURL)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (p *Payload) IsVersionCommitted(branch string) bool {
|
||||
refName := plumbing.NewBranchReferenceName(branch)
|
||||
ref, err := p.Repository.Reference(refName, false)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
commitIter, err := p.Repository.Log(&git.LogOptions{From: ref.Hash()})
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
err = commitIter.ForEach(func(commit *object.Commit) error {
|
||||
if strings.Contains(commit.Message, fmt.Sprintf("Update %s", p.Version.DashboardUID)) && strings.Contains(commit.Message, fmt.Sprintf("version %d", p.Version.ID)) {
|
||||
return fmt.Errorf("version already committed")
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
return err != nil
|
||||
}
|
||||
|
||||
func genAuth(user, password string) *http.BasicAuth {
|
||||
return &http.BasicAuth{
|
||||
Username: user,
|
||||
Password: password,
|
||||
}
|
||||
}
|
||||
|
||||
func commitDashboard(repo *git.Repository, content []byte, commitMsg, dashboardTitle, folderTitle, gitRepoDirectory, keyFile string, author, committer *object.Signature) (err error) {
|
||||
var (
|
||||
file billy.File
|
||||
signer *openpgp.Entity
|
||||
worktree *git.Worktree
|
||||
)
|
||||
|
||||
if strings.TrimSpace(keyFile) != "" {
|
||||
signer, err = getSigner(keyFile)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
worktree, err = repo.Worktree()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err = fs.MkdirAll(folderTitle, 0755); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
filePath := filepath.Join(folderTitle, fmt.Sprintf("%s.json", dashboardTitle))
|
||||
if file, err = fs.Create(filePath); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if _, err = file.Write(content); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err = file.Close(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if _, err = worktree.Add(filePath); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
_, err = worktree.Commit(
|
||||
commitMsg,
|
||||
&git.CommitOptions{
|
||||
Author: author,
|
||||
Committer: committer,
|
||||
SignKey: signer,
|
||||
},
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (p *Payload) CreateCommit() error {
|
||||
var commitmsg string
|
||||
|
||||
if p.Version.Message != "" {
|
||||
commitmsg = fmt.Sprintf(
|
||||
"%s: Update %s to version %d => %s",
|
||||
p.Dashboard.Title,
|
||||
p.Version.DashboardUID,
|
||||
p.Version.ID,
|
||||
p.Version.Message,
|
||||
)
|
||||
} else {
|
||||
commitmsg = fmt.Sprintf(
|
||||
"%s: Update %s to version %d",
|
||||
p.Dashboard.Title,
|
||||
p.Version.DashboardUID,
|
||||
p.Version.ID,
|
||||
)
|
||||
}
|
||||
|
||||
p.UpdateAuthor(p.Version.Created)
|
||||
p.UpdateCommitter()
|
||||
|
||||
return commitDashboard(
|
||||
p.Repository,
|
||||
p.Content,
|
||||
commitmsg,
|
||||
p.Dashboard.Title,
|
||||
p.DashboardInfo.FolderTitle,
|
||||
p.Directory,
|
||||
p.KeyFile,
|
||||
p.Author,
|
||||
p.Committer,
|
||||
)
|
||||
}
|
||||
|
||||
func (p *Payload) PushToRemote(user, password string) error {
|
||||
origin, err := p.Repository.Remote("origin")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return origin.Push(
|
||||
&git.PushOptions{
|
||||
Auth: genAuth(user, password),
|
||||
Progress: os.Stdout,
|
||||
},
|
||||
)
|
||||
}
|
28
pkg/git/signer.go
Normal file
28
pkg/git/signer.go
Normal file
|
@ -0,0 +1,28 @@
|
|||
package git
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/ProtonMail/go-crypto/openpgp"
|
||||
"github.com/ProtonMail/go-crypto/openpgp/armor"
|
||||
)
|
||||
|
||||
func getSigner(keyFile string) (*openpgp.Entity, error) {
|
||||
file, err := os.Open(keyFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
block, err := armor.Decode(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
entityList, err := openpgp.ReadKeyRing(block.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return entityList[0], nil
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package grafana
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
@ -8,9 +9,30 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
type BoardProperties struct {
|
||||
IsStarred bool `json:"isStarred,omitempty"`
|
||||
IsHome bool `json:"isHome,omitempty"`
|
||||
IsSnapshot bool `json:"isSnapshot,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
CanSave bool `json:"canSave"`
|
||||
CanEdit bool `json:"canEdit"`
|
||||
CanStar bool `json:"canStar"`
|
||||
Slug string `json:"slug"`
|
||||
Expires time.Time `json:"expires"`
|
||||
Created time.Time `json:"created"`
|
||||
Updated time.Time `json:"updated"`
|
||||
UpdatedBy string `json:"updatedBy"`
|
||||
CreatedBy string `json:"createdBy"`
|
||||
Version int `json:"version"`
|
||||
FolderID int `json:"folderId"`
|
||||
FolderTitle string `json:"folderTitle"`
|
||||
FolderURL string `json:"folderUrl"`
|
||||
}
|
||||
|
||||
type DashboardVersion struct {
|
||||
ID uint `json:"id"`
|
||||
DashboardID uint `json:"dashboardId"`
|
||||
DashboardUID string `json:"uid"`
|
||||
ParentVersion uint `json:"parentVersion"`
|
||||
RestoredFrom uint `json:"restoredFrom"`
|
||||
Version uint `json:"version"`
|
||||
|
@ -19,6 +41,42 @@ type DashboardVersion struct {
|
|||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
func (c *Client) getRawDashboardByUID(ctx context.Context, path string) ([]byte, BoardProperties, error) {
|
||||
raw, code, err := c.get(ctx, fmt.Sprintf("api/dashboards/%s", path), nil)
|
||||
if err != nil {
|
||||
return nil, BoardProperties{}, err
|
||||
}
|
||||
if code != 200 {
|
||||
return raw, BoardProperties{}, fmt.Errorf("HTTP error %d: returns %s", code, raw)
|
||||
}
|
||||
var result struct {
|
||||
Meta BoardProperties `json:"meta"`
|
||||
}
|
||||
dec := json.NewDecoder(bytes.NewReader(raw))
|
||||
dec.UseNumber()
|
||||
if err := dec.Decode(&result); err != nil {
|
||||
return raw, BoardProperties{}, fmt.Errorf("failed unmarshalling dashboard from path %s: %v", path, err)
|
||||
}
|
||||
return raw, result.Meta, nil
|
||||
}
|
||||
|
||||
func (c *Client) getRawDashboardFromVersion(ctx context.Context, path string) ([]byte, DashboardVersion, error) {
|
||||
var versionInfo DashboardVersion
|
||||
raw, code, err := c.get(ctx, fmt.Sprintf("api/dashboards/%s", path), nil)
|
||||
if err != nil {
|
||||
return nil, versionInfo, err
|
||||
}
|
||||
if code != 200 {
|
||||
return raw, versionInfo, fmt.Errorf("HTTP error %d: returns %s", code, raw)
|
||||
}
|
||||
dec := json.NewDecoder(bytes.NewReader(raw))
|
||||
dec.UseNumber()
|
||||
if err := dec.Decode(&versionInfo); err != nil {
|
||||
return raw, versionInfo, fmt.Errorf("failed unmarshalling dashboard from path %s: %v", path, err)
|
||||
}
|
||||
return raw, versionInfo, nil
|
||||
}
|
||||
|
||||
func queryParams(params ...QueryParam) url.Values {
|
||||
u := url.URL{}
|
||||
q := u.Query()
|
||||
|
@ -28,14 +86,14 @@ func queryParams(params ...QueryParam) url.Values {
|
|||
return q
|
||||
}
|
||||
|
||||
func (c *Client) GetDashboardVersionsByDashboardID(ctx context.Context, dashboardID uint, params ...QueryParam) ([]DashboardVersion, error) {
|
||||
func (c *Client) GetDashboardVersionsByDashboardUID(ctx context.Context, uid string, params ...QueryParam) ([]DashboardVersion, error) {
|
||||
var (
|
||||
raw []byte
|
||||
code int
|
||||
err error
|
||||
)
|
||||
|
||||
if raw, code, err = c.get(ctx, fmt.Sprintf("api/dashboards/id/%d/versions", dashboardID), queryParams(params...)); err != nil {
|
||||
if raw, code, err = c.get(ctx, fmt.Sprintf("api/dashboards/uid/%s/versions", uid), queryParams(params...)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if code != 200 {
|
||||
|
@ -47,6 +105,14 @@ func (c *Client) GetDashboardVersionsByDashboardID(ctx context.Context, dashboar
|
|||
return versions, err
|
||||
}
|
||||
|
||||
func (c *Client) GetRawDashboardByUID(ctx context.Context, uid string) ([]byte, BoardProperties, error) {
|
||||
return c.getRawDashboardByUID(ctx, "uid/"+uid)
|
||||
}
|
||||
|
||||
func (c *Client) GetRawDashboardByUIDAndVersion(ctx context.Context, uid string, version uint) ([]byte, DashboardVersion, error) {
|
||||
return c.getRawDashboardFromVersion(ctx, "uid/"+uid+"/versions/"+fmt.Sprint(version))
|
||||
}
|
||||
|
||||
func (c *Client) SearchDashboards(ctx context.Context, query string, starred bool, tags ...string) ([]FoundBoard, error) {
|
||||
params := []SearchParam{
|
||||
SearchType(SearchTypeDashboard),
|
||||
|
@ -58,3 +124,14 @@ func (c *Client) SearchDashboards(ctx context.Context, query string, starred boo
|
|||
}
|
||||
return c.Search(ctx, params...)
|
||||
}
|
||||
|
||||
func ConvertRawToIndent(raw []byte) (string, error) {
|
||||
var buf bytes.Buffer
|
||||
|
||||
err := json.Indent(&buf, raw, "", " ")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error pritty-printing raw json string: %v", err)
|
||||
}
|
||||
|
||||
return buf.String(), nil
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package grafana
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -74,7 +73,3 @@ func (c *Client) doRequest(ctx context.Context, method, query string, params url
|
|||
func (c *Client) get(ctx context.Context, query string, params url.Values) ([]byte, int, error) {
|
||||
return c.doRequest(ctx, "GET", query, params, nil)
|
||||
}
|
||||
|
||||
func (c *Client) post(ctx context.Context, query string, params url.Values, body []byte) ([]byte, int, error) {
|
||||
return c.doRequest(ctx, "POST", query, params, bytes.NewBuffer(body))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue