forked from grafana/grafana
-
Notifications
You must be signed in to change notification settings - Fork 0
/
services.go
180 lines (143 loc) · 3.96 KB
/
services.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
package services
import (
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net"
"net/http"
"net/url"
"path"
"runtime"
"time"
"github.com/grafana/grafana/pkg/cmd/grafana-cli/logger"
m "github.com/grafana/grafana/pkg/cmd/grafana-cli/models"
)
var (
IoHelper m.IoUtil = IoUtilImp{}
HttpClient http.Client
grafanaVersion string
)
func Init(version string, skipTLSVerify bool) {
grafanaVersion = version
tr := &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
DualStack: true,
}).DialContext,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
TLSClientConfig: &tls.Config{
InsecureSkipVerify: skipTLSVerify,
},
}
HttpClient = http.Client{
Timeout: 10 * time.Second,
Transport: tr,
}
}
func ListAllPlugins(repoUrl string) (m.PluginRepo, error) {
body, err := sendRequest(repoUrl, "repo")
if err != nil {
logger.Info("Failed to send request", "error", err)
return m.PluginRepo{}, fmt.Errorf("Failed to send request. error: %v", err)
}
if err != nil {
return m.PluginRepo{}, err
}
var data m.PluginRepo
err = json.Unmarshal(body, &data)
if err != nil {
logger.Info("Failed to unmarshal plugin repo response error:", err)
return m.PluginRepo{}, err
}
return data, nil
}
func ReadPlugin(pluginDir, pluginName string) (m.InstalledPlugin, error) {
distPluginDataPath := path.Join(pluginDir, pluginName, "dist", "plugin.json")
var data []byte
var err error
data, err = IoHelper.ReadFile(distPluginDataPath)
if err != nil {
pluginDataPath := path.Join(pluginDir, pluginName, "plugin.json")
data, err = IoHelper.ReadFile(pluginDataPath)
if err != nil {
return m.InstalledPlugin{}, errors.New("Could not find dist/plugin.json or plugin.json on " + pluginName + " in " + pluginDir)
}
}
res := m.InstalledPlugin{}
json.Unmarshal(data, &res)
if res.Info.Version == "" {
res.Info.Version = "0.0.0"
}
if res.Id == "" {
return m.InstalledPlugin{}, errors.New("could not find plugin " + pluginName + " in " + pluginDir)
}
return res, nil
}
func GetLocalPlugins(pluginDir string) []m.InstalledPlugin {
result := make([]m.InstalledPlugin, 0)
files, _ := IoHelper.ReadDir(pluginDir)
for _, f := range files {
res, err := ReadPlugin(pluginDir, f.Name())
if err == nil {
result = append(result, res)
}
}
return result
}
func RemoveInstalledPlugin(pluginPath, pluginName string) error {
logger.Infof("Removing plugin: %v\n", pluginName)
pluginDir := path.Join(pluginPath, pluginName)
_, err := IoHelper.Stat(pluginDir)
if err != nil {
return err
}
return IoHelper.RemoveAll(pluginDir)
}
func GetPlugin(pluginId, repoUrl string) (m.Plugin, error) {
body, err := sendRequest(repoUrl, "repo", pluginId)
if err != nil {
logger.Info("Failed to send request", "error", err)
return m.Plugin{}, fmt.Errorf("Failed to send request. error: %v", err)
}
if err != nil {
return m.Plugin{}, err
}
var data m.Plugin
err = json.Unmarshal(body, &data)
if err != nil {
logger.Info("Failed to unmarshal plugin repo response error:", err)
return m.Plugin{}, err
}
return data, nil
}
func sendRequest(repoUrl string, subPaths ...string) ([]byte, error) {
u, _ := url.Parse(repoUrl)
for _, v := range subPaths {
u.Path = path.Join(u.Path, v)
}
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
req.Header.Set("grafana-version", grafanaVersion)
req.Header.Set("grafana-os", runtime.GOOS)
req.Header.Set("grafana-arch", runtime.GOARCH)
req.Header.Set("User-Agent", "grafana "+grafanaVersion)
if err != nil {
return []byte{}, err
}
res, err := HttpClient.Do(req)
if err != nil {
return []byte{}, err
}
if res.StatusCode/100 != 2 {
return []byte{}, fmt.Errorf("Api returned invalid status: %s", res.Status)
}
body, err := ioutil.ReadAll(res.Body)
defer res.Body.Close()
return body, err
}