This is small tool to help you interact with Grafana API. It could be used to create new Organization, add new user and provision basic datasources from templates, ie. Prometheus, Loki, Tempo.
You can test it using small demo code but you need to have your grafana instance running and available in some URL. You also need to have local Grafana user/pass with admin privileges.
export DEV_GRAFANA_URL=your-url
export DEV_GRAFANA_USER=your-user
export DEV_GRAFANA_PASS='your-pass-with-special-chars'
Grafana Struct
Keeps basic data about target Grafana like url, username, password and base64 encoded user:pass needed for Basic Authentication. This will be added into Authorization Header.
package main
import (
"encoding/base64"
"fmt"
)
type Grafana struct {
Url string
User string
Pass string
Credentials string
}
func EncodeCredentials(g Grafana) Grafana {
g.Credentials = base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", g.User, g.Pass)))
return g
}
Organization Struct
Keeps basic data about Organization and implements specific HTTP calls related to Organization, ie. GetOrgById or CreateOrg. It is also populated from HTTP responses by transforming (unmarshaling) JSON into struct.
package main
import (
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"strconv"
"strings"
)
type Org struct {
Id int `json:"orgId"`
Name string `json:"name"`
}
// Input Grafana must be initialized with credentials
func GetOrgById(g Grafana, id int) Org {
// Cretate HTTP Request to given Grafana for given Id
url := g.Url + "/api/orgs/" + strconv.Itoa(id)
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Basic "+g.Credentials)
client := &http.Client{}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
// Return the Org
body, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
fmt.Println("Response Status:", res.StatusCode)
if res.StatusCode != http.StatusOK {
log.Fatal("Couldn't fetch Org: \n", string(body))
}
var org Org
if err := json.Unmarshal(body, &org); err != nil {
panic(err)
}
return org
}
// Input Grafana must be initialized with credentials
func GetOrgByName(g Grafana, name string) Org {
// Cretate HTTP Request to given Grafana for given Id
url := g.Url + "/api/orgs/name/" + name
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Basic "+g.Credentials)
client := &http.Client{}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
// Return the Org
body, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
fmt.Println("Response Status:", res.StatusCode)
if res.StatusCode != http.StatusOK {
log.Fatal("Couldn't fetch Org: \n", string(body))
}
var org Org
if err := json.Unmarshal(body, &org); err != nil {
panic(err)
}
return org
}
// Create Org
func CreateOrg(g Grafana, name string) int {
type OrgResponse struct {
Message string `json:"message"`
Id int `json:"orgId"`
}
// Cretate HTTP Request to given Grafana for given Id
url := g.Url + "/api/orgs"
post_body := strings.NewReader(fmt.Sprintf(`{"name": "%s"}`, name))
req, _ := http.NewRequest("POST", url, post_body)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Basic "+g.Credentials)
client := &http.Client{}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
// Return the Org
body, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
fmt.Println("Response Status:", res.StatusCode, string(body))
if res.StatusCode != http.StatusOK {
log.Fatal("Couldn't fetch Org: \n", string(body))
}
var org_res OrgResponse
if err := json.Unmarshal(body, &org_res); err != nil {
panic(err)
}
return org_res.Id
}
Test Code
This is simple test to show capabilities
package main
import (
"fmt"
"os"
)
func main() {
dev_grafana := EncodeCredentials(Grafana{
Url: os.Getenv("DEV_GRAFANA_URL"),
User: os.Getenv("DEV_GRAFANA_USER"),
// If your pass has special characters, export with single quotes
Pass: os.Getenv("DEV_GRAFANA_PASS"),
})
current_org := GetOrgById(dev_grafana, 1)
fmt.Println("Organization ID:", current_org.Id, "Name:", current_org.Name)
current_org = GetOrgByName(dev_grafana, "Main Org.")
fmt.Println("Organization ID:", current_org.Id, "Name:", current_org.Name)
new_org_id := CreateOrg(dev_grafana, "test-org-1")
fmt.Println("New Organization ID:", new_org_id)
}