diff --git a/cmd/stateth/stateth.go b/cmd/stateth/stateth.go index b46a3b8e62..325f5836f0 100644 --- a/cmd/stateth/stateth.go +++ b/cmd/stateth/stateth.go @@ -38,6 +38,13 @@ var ( influxdbPort int // expose port for the InfluxDB HTTP interface ) +const ( + influxdbAdminUser = "admin" // admin username for InfluxDB + influxdbAdminPass = "admin" // admin password for InfluxDB + grafanaUser = "admin" // default Grafana username - should not be changed here without first updating the docker image + grafanaPass = "admin" // default Grafana password - should not be changed here without first udpating the docker image +) + func main() { app := cli.NewApp() app.Name = "stateth" @@ -102,8 +109,8 @@ func main() { }() fmt.Println(fmt.Sprintf("grafana listening on http://localhost:%d", grafanaPort)) - fmt.Println("username: admin") - fmt.Println("password: admin") + fmt.Println(fmt.Sprintf("username: %s", grafanaUser)) + fmt.Println(fmt.Sprintf("password: %s", grafanaPass)) fmt.Println() fmt.Println("waiting for SIGINT or SIGTERM (CTRL^C) to stop service and remove containers...") <-done @@ -138,7 +145,7 @@ func runInfluxDB(c *cli.Context) error { } log.Info("running influxdb docker container", "container", fmt.Sprintf("%s_influxdb", dockerPrefix)) - command = strings.Split(fmt.Sprintf("docker run --network %s --name %s_influxdb -e INFLUXDB_DB=metrics -e INFLUXDB_ADMIN_USER=admin -e INFLUXDB_ADMIN_PASSWORD=admin -p %d:8086 -d influxdb:1.5.2", dockerPrefix, dockerPrefix, influxdbPort), " ") + command = strings.Split(fmt.Sprintf("docker run --network %s --name %s_influxdb -e INFLUXDB_DB=metrics -e INFLUXDB_ADMIN_USER=%s -e INFLUXDB_ADMIN_PASSWORD=%s -p %d:8086 -d influxdb:1.5.2", dockerPrefix, dockerPrefix, influxdbAdminUser, influxdbAdminPass, influxdbPort), " ") r, err = exec.Command(command[0], command[1:]...).CombinedOutput() if err != nil { log.Error(string(r)) @@ -193,7 +200,7 @@ func cleanupContainers(c *cli.Context) error { func importGrafanaDatasource(c *cli.Context) error { log.Info("importing grafana datasource") - gclient, err := gapi.New("admin:admin", fmt.Sprintf("http://localhost:%d", grafanaPort)) + gclient, err := gapi.New(fmt.Sprintf("%s:%s", grafanaUser, grafanaPass), fmt.Sprintf("http://localhost:%d", grafanaPort)) if err != nil { log.Warn(err.Error()) return nil @@ -202,11 +209,11 @@ func importGrafanaDatasource(c *cli.Context) error { dataSource := &gapi.DataSource{ Name: "metrics", Type: "influxdb", - URL: "http://stateth_influxdb:8086", + URL: fmt.Sprintf("http://%s_influxdb:%d", dockerPrefix, influxdbPort), Access: "proxy", Database: "metrics", - User: "admin", - Password: "admin", + User: influxdbAdminUser, + Password: influxdbAdminPass, IsDefault: true, BasicAuth: false, } @@ -222,7 +229,7 @@ func importGrafanaDatasource(c *cli.Context) error { func importGrafanaDashboard(c *cli.Context) error { log.Info("importing grafana dashboards") - gclient, err := gapi.New("admin:admin", fmt.Sprintf("http://localhost:%d", grafanaPort)) + gclient, err := gapi.New(fmt.Sprintf("%s:%s", grafanaUser, grafanaPass), fmt.Sprintf("http://localhost:%d", grafanaPort)) if err != nil { log.Warn(err.Error()) return nil diff --git a/vendor/github.com/teemupo/go-grafana-api/LICENSE b/vendor/github.com/teemupo/go-grafana-api/LICENSE new file mode 100644 index 0000000000..8f71f43fee --- /dev/null +++ b/vendor/github.com/teemupo/go-grafana-api/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/vendor/github.com/teemupo/go-grafana-api/README.md b/vendor/github.com/teemupo/go-grafana-api/README.md new file mode 100644 index 0000000000..581af01ddb --- /dev/null +++ b/vendor/github.com/teemupo/go-grafana-api/README.md @@ -0,0 +1,11 @@ +# grafana-api-golang-client + +Grafana HTTP API Client for Go + +## Tests + +To run the tests: + +``` +go test +``` diff --git a/vendor/github.com/teemupo/go-grafana-api/admin.go b/vendor/github.com/teemupo/go-grafana-api/admin.go new file mode 100644 index 0000000000..3da1ae9229 --- /dev/null +++ b/vendor/github.com/teemupo/go-grafana-api/admin.go @@ -0,0 +1,46 @@ +package gapi + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io/ioutil" + + "github.com/grafana/grafana/pkg/api/dtos" +) + +func (c *Client) CreateUserForm(settings dtos.AdminCreateUserForm) error { + data, err := json.Marshal(settings) + req, err := c.newRequest("POST", "/api/admin/users", bytes.NewBuffer(data)) + if err != nil { + return err + } + resp, err := c.Do(req) + if err != nil { + return err + } + data, err = ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + if resp.StatusCode != 200 { + return errors.New(resp.Status) + } + return err +} + +func (c *Client) DeleteUser(id int64) error { + req, err := c.newRequest("DELETE", fmt.Sprintf("/api/admin/users/%d", id), nil) + if err != nil { + return err + } + resp, err := c.Do(req) + if err != nil { + return err + } + if resp.StatusCode != 200 { + return errors.New(resp.Status) + } + return err +} diff --git a/vendor/github.com/teemupo/go-grafana-api/alertnotification.go b/vendor/github.com/teemupo/go-grafana-api/alertnotification.go new file mode 100644 index 0000000000..39a32b9f40 --- /dev/null +++ b/vendor/github.com/teemupo/go-grafana-api/alertnotification.go @@ -0,0 +1,112 @@ +package gapi + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io/ioutil" +) + +type AlertNotification struct { + Id int64 `json:"id,omitempty"` + Name string `json:"name"` + Type string `json:"type"` + IsDefault bool `json:"isDefault"` + Settings interface{} `json:"settings"` +} + +func (c *Client) AlertNotification(id int64) (*AlertNotification, error) { + path := fmt.Sprintf("/api/alert-notifications/%d", id) + req, err := c.newRequest("GET", path, nil) + if err != nil { + return nil, err + } + + resp, err := c.Do(req) + if err != nil { + return nil, err + } + if resp.StatusCode != 200 { + return nil, errors.New(resp.Status) + } + + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + result := &AlertNotification{} + err = json.Unmarshal(data, &result) + return result, err +} + +func (c *Client) NewAlertNotification(a *AlertNotification) (int64, error) { + data, err := json.Marshal(a) + if err != nil { + return 0, err + } + req, err := c.newRequest("POST", "/api/alert-notifications", bytes.NewBuffer(data)) + if err != nil { + return 0, err + } + + resp, err := c.Do(req) + if err != nil { + return 0, err + } + if resp.StatusCode != 200 { + return 0, errors.New(resp.Status) + } + + data, err = ioutil.ReadAll(resp.Body) + if err != nil { + return 0, err + } + + result := struct { + Id int64 `json:"id"` + }{} + err = json.Unmarshal(data, &result) + return result.Id, err +} + +func (c *Client) UpdateAlertNotification(a *AlertNotification) error { + path := fmt.Sprintf("/api/alert-notifications/%d", a.Id) + data, err := json.Marshal(a) + if err != nil { + return err + } + req, err := c.newRequest("PUT", path, bytes.NewBuffer(data)) + if err != nil { + return err + } + + resp, err := c.Do(req) + if err != nil { + return err + } + if resp.StatusCode != 200 { + return errors.New(resp.Status) + } + + return nil +} + +func (c *Client) DeleteAlertNotification(id int64) error { + path := fmt.Sprintf("/api/alert-notifications/%d", id) + req, err := c.newRequest("DELETE", path, nil) + if err != nil { + return err + } + + resp, err := c.Do(req) + if err != nil { + return err + } + if resp.StatusCode != 200 { + return errors.New(resp.Status) + } + + return nil +} diff --git a/vendor/github.com/teemupo/go-grafana-api/client.go b/vendor/github.com/teemupo/go-grafana-api/client.go new file mode 100644 index 0000000000..d92ba883a8 --- /dev/null +++ b/vendor/github.com/teemupo/go-grafana-api/client.go @@ -0,0 +1,63 @@ +package gapi + +import ( + "bytes" + "fmt" + "io" + "log" + "net/http" + "net/url" + "os" + "path" + "strings" +) + +type Client struct { + key string + baseURL url.URL + *http.Client +} + +//New creates a new grafana client +//auth can be in user:pass format, or it can be an api key +func New(auth, baseURL string) (*Client, error) { + u, err := url.Parse(baseURL) + if err != nil { + return nil, err + } + key := "" + if strings.Contains(auth, ":") { + split := strings.Split(auth, ":") + u.User = url.UserPassword(split[0], split[1]) + } else { + key = fmt.Sprintf("Bearer %s", auth) + } + return &Client{ + key, + *u, + &http.Client{}, + }, nil +} + +func (c *Client) newRequest(method, requestPath string, body io.Reader) (*http.Request, error) { + url := c.baseURL + url.Path = path.Join(url.Path, requestPath) + req, err := http.NewRequest(method, url.String(), body) + if err != nil { + return req, err + } + if c.key != "" { + req.Header.Add("Authorization", c.key) + } + + if os.Getenv("GF_LOG") != "" { + if body == nil { + log.Println("request to ", url.String(), "with no body data") + } else { + log.Println("request to ", url.String(), "with body data", body.(*bytes.Buffer).String()) + } + } + + req.Header.Add("Content-Type", "application/json") + return req, err +} diff --git a/vendor/github.com/teemupo/go-grafana-api/dashboard.go b/vendor/github.com/teemupo/go-grafana-api/dashboard.go new file mode 100644 index 0000000000..ca45dc9a07 --- /dev/null +++ b/vendor/github.com/teemupo/go-grafana-api/dashboard.go @@ -0,0 +1,100 @@ +package gapi + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io/ioutil" +) + +type DashboardMeta struct { + IsStarred bool `json:"isStarred"` + Slug string `json:"slug"` +} + +type DashboardSaveResponse struct { + Slug string `json:"slug"` + Status string `json:"status"` + Version int64 `json:"version"` +} + +type Dashboard struct { + Meta DashboardMeta `json:"meta"` + Model map[string]interface{} `json:"dashboard"` +} + +func (c *Client) SaveDashboard(model map[string]interface{}, overwrite bool) (*DashboardSaveResponse, error) { + wrapper := map[string]interface{}{ + "dashboard": model, + "overwrite": overwrite, + } + data, err := json.Marshal(wrapper) + if err != nil { + return nil, err + } + req, err := c.newRequest("POST", "/api/dashboards/db", bytes.NewBuffer(data)) + if err != nil { + return nil, err + } + + resp, err := c.Do(req) + if err != nil { + return nil, err + } + if resp.StatusCode != 200 { + return nil, errors.New(resp.Status) + } + + data, err = ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + result := &DashboardSaveResponse{} + err = json.Unmarshal(data, &result) + return result, err +} + +func (c *Client) Dashboard(slug string) (*Dashboard, error) { + path := fmt.Sprintf("/api/dashboards/db/%s", slug) + req, err := c.newRequest("GET", path, nil) + if err != nil { + return nil, err + } + + resp, err := c.Do(req) + if err != nil { + return nil, err + } + if resp.StatusCode != 200 { + return nil, errors.New(resp.Status) + } + + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + result := &Dashboard{} + err = json.Unmarshal(data, &result) + return result, err +} + +func (c *Client) DeleteDashboard(slug string) error { + path := fmt.Sprintf("/api/dashboards/db/%s", slug) + req, err := c.newRequest("DELETE", path, nil) + if err != nil { + return err + } + + resp, err := c.Do(req) + if err != nil { + return err + } + if resp.StatusCode != 200 { + return errors.New(resp.Status) + } + + return nil +} diff --git a/vendor/github.com/teemupo/go-grafana-api/datasource.go b/vendor/github.com/teemupo/go-grafana-api/datasource.go new file mode 100644 index 0000000000..ab42b88e60 --- /dev/null +++ b/vendor/github.com/teemupo/go-grafana-api/datasource.go @@ -0,0 +1,140 @@ +package gapi + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io/ioutil" +) + +type DataSource struct { + Id int64 `json:"id,omitempty"` + Name string `json:"name"` + Type string `json:"type"` + URL string `json:"url"` + Access string `json:"access"` + + Database string `json:"database,omitempty"` + User string `json:"user,omitempty"` + Password string `json:"password,omitempty"` + + OrgId int64 `json:"orgId,omitempty"` + IsDefault bool `json:"isDefault"` + + BasicAuth bool `json:"basicAuth"` + BasicAuthUser string `json:"basicAuthUser,omitempty"` + BasicAuthPassword string `json:"basicAuthPassword,omitempty"` + + JSONData JSONData `json:"jsonData,omitempty"` + SecureJSONData SecureJSONData `json:"secureJsonData,omitempty"` +} + +// JSONData is a representation of the datasource `jsonData` property +type JSONData struct { + AssumeRoleArn string `json:"assumeRoleArn,omitempty"` + AuthType string `json:"authType,omitempty"` + CustomMetricsNamespaces string `json:"customMetricsNamespaces,omitempty"` + DefaultRegion string `json:"defaultRegion,omitempty"` +} + +// SecureJSONData is a representation of the datasource `secureJsonData` property +type SecureJSONData struct { + AccessKey string `json:"accessKey,omitempty"` + SecretKey string `json:"secretKey,omitempty"` +} + +func (c *Client) NewDataSource(s *DataSource) (int64, error) { + data, err := json.Marshal(s) + if err != nil { + return 0, err + } + req, err := c.newRequest("POST", "/api/datasources", bytes.NewBuffer(data)) + if err != nil { + return 0, err + } + + resp, err := c.Do(req) + if err != nil { + return 0, err + } + if resp.StatusCode != 200 { + return 0, errors.New(resp.Status) + } + + data, err = ioutil.ReadAll(resp.Body) + if err != nil { + return 0, err + } + + result := struct { + Id int64 `json:"id"` + }{} + err = json.Unmarshal(data, &result) + return result.Id, err +} + +func (c *Client) UpdateDataSource(s *DataSource) error { + path := fmt.Sprintf("/api/datasources/%d", s.Id) + data, err := json.Marshal(s) + if err != nil { + return err + } + req, err := c.newRequest("PUT", path, bytes.NewBuffer(data)) + if err != nil { + return err + } + + resp, err := c.Do(req) + if err != nil { + return err + } + if resp.StatusCode != 200 { + return errors.New(resp.Status) + } + + return nil +} + +func (c *Client) DataSource(id int64) (*DataSource, error) { + path := fmt.Sprintf("/api/datasources/%d", id) + req, err := c.newRequest("GET", path, nil) + if err != nil { + return nil, err + } + + resp, err := c.Do(req) + if err != nil { + return nil, err + } + if resp.StatusCode != 200 { + return nil, errors.New(resp.Status) + } + + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + result := &DataSource{} + err = json.Unmarshal(data, &result) + return result, err +} + +func (c *Client) DeleteDataSource(id int64) error { + path := fmt.Sprintf("/api/datasources/%d", id) + req, err := c.newRequest("DELETE", path, nil) + if err != nil { + return err + } + + resp, err := c.Do(req) + if err != nil { + return err + } + if resp.StatusCode != 200 { + return errors.New(resp.Status) + } + + return nil +} diff --git a/vendor/github.com/teemupo/go-grafana-api/orgs.go b/vendor/github.com/teemupo/go-grafana-api/orgs.go new file mode 100644 index 0000000000..5a38732c70 --- /dev/null +++ b/vendor/github.com/teemupo/go-grafana-api/orgs.go @@ -0,0 +1,70 @@ +package gapi + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io/ioutil" +) + +type Org struct { + Id int64 + Name string +} + +func (c *Client) Orgs() ([]Org, error) { + orgs := make([]Org, 0) + + req, err := c.newRequest("GET", "/api/orgs/", nil) + if err != nil { + return orgs, err + } + resp, err := c.Do(req) + if err != nil { + return orgs, err + } + if resp.StatusCode != 200 { + return orgs, errors.New(resp.Status) + } + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + return orgs, err + } + err = json.Unmarshal(data, &orgs) + return orgs, err +} + +func (c *Client) NewOrg(name string) error { + settings := map[string]string{ + "name": name, + } + data, err := json.Marshal(settings) + req, err := c.newRequest("POST", "/api/orgs", bytes.NewBuffer(data)) + if err != nil { + return err + } + resp, err := c.Do(req) + if err != nil { + return err + } + if resp.StatusCode != 200 { + return errors.New(resp.Status) + } + return err +} + +func (c *Client) DeleteOrg(id int64) error { + req, err := c.newRequest("DELETE", fmt.Sprintf("/api/orgs/%d", id), nil) + if err != nil { + return err + } + resp, err := c.Do(req) + if err != nil { + return err + } + if resp.StatusCode != 200 { + return errors.New(resp.Status) + } + return err +} diff --git a/vendor/github.com/teemupo/go-grafana-api/user.go b/vendor/github.com/teemupo/go-grafana-api/user.go new file mode 100644 index 0000000000..13a6e6ff4f --- /dev/null +++ b/vendor/github.com/teemupo/go-grafana-api/user.go @@ -0,0 +1,39 @@ +package gapi + +import ( + "encoding/json" + "errors" + "io/ioutil" +) + +type User struct { + Id int64 + Email string + Name string + Login string + IsAdmin bool +} + +func (c *Client) Users() ([]User, error) { + users := make([]User, 0) + req, err := c.newRequest("GET", "/api/users", nil) + if err != nil { + return users, err + } + resp, err := c.Do(req) + if err != nil { + return users, err + } + if resp.StatusCode != 200 { + return users, errors.New(resp.Status) + } + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + return users, err + } + err = json.Unmarshal(data, &users) + if err != nil { + return users, err + } + return users, err +} diff --git a/vendor/vendor.json b/vendor/vendor.json index fdc7789364..7bb4459da4 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -489,6 +489,12 @@ "revision": "ae970a0732be3a1f5311da86118d37b9f4bd2a5a", "revisionTime": "2018-05-02T07:23:49Z" }, + { + "checksumSHA1": "2OAzyUvaUKVZkRx9f8NlbHT9cc0=", + "path": "github.com/teemupo/go-grafana-api", + "revision": "7380665c19d6fb0b587e654f25d2604787d890c8", + "revisionTime": "2018-02-22T10:42:15Z" + }, { "checksumSHA1": "TT1rac6kpQp2vz24m5yDGUNQ/QQ=", "path": "golang.org/x/crypto/cast5",