From 64f371a32d796b69e582759e0d984ccaaa7367db Mon Sep 17 00:00:00 2001 From: bergquist Date: Tue, 29 Nov 2016 16:51:38 +0100 Subject: [PATCH 01/12] tech: upgrade package json to v4.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ab84c8d90dd..b358c655c04 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "company": "Coding Instinct AB" }, "name": "grafana", - "version": "4.0.0-beta2", + "version": "4.0.0", "repository": { "type": "git", "url": "http://github.com/grafana/grafana.git" From 231492d4437f52660c169384d68ba12072c75848 Mon Sep 17 00:00:00 2001 From: bergquist Date: Tue, 29 Nov 2016 17:03:49 +0100 Subject: [PATCH 02/12] tech(build): change windows build branch --- scripts/trigger_windows_build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/trigger_windows_build.sh b/scripts/trigger_windows_build.sh index 521a365a299..9ba5c5eddb2 100755 --- a/scripts/trigger_windows_build.sh +++ b/scripts/trigger_windows_build.sh @@ -5,5 +5,5 @@ _token=$1 curl \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${_token}" \ - -X POST -d '{ "accountName": "Torkeldegaard", "projectSlug": "grafana","branch": "master","environmentVariables": {}}' \ + -X POST -d '{ "accountName": "Torkeldegaard", "projectSlug": "grafana","branch": "v4.0.x","environmentVariables": {}}' \ https://ci.appveyor.com/api/builds From 567c2a1799c40158acd93fa160477389b99cd8a6 Mon Sep 17 00:00:00 2001 From: bergquist Date: Tue, 29 Nov 2016 17:31:15 +0100 Subject: [PATCH 03/12] tech(build): update branch to package --- circle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circle.yml b/circle.yml index 2422715bda3..bbdcb05023c 100644 --- a/circle.yml +++ b/circle.yml @@ -24,7 +24,7 @@ test: deployment: master: - branch: master + branch: v4.0.x owner: grafana commands: - ./scripts/trigger_grafana_packer.sh ${TRIGGER_GRAFANA_PACKER_CIRCLECI_TOKEN} From 25a5fc465c153af4c5d331d5fdf65483454275d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 29 Nov 2016 11:36:56 -0500 Subject: [PATCH 04/12] fix(row): fixed dropping new panels onto panels, should split target panel --- public/app/features/dashboard/row/row_ctrl.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/features/dashboard/row/row_ctrl.ts b/public/app/features/dashboard/row/row_ctrl.ts index e28f576c8ba..ce92821dfef 100644 --- a/public/app/features/dashboard/row/row_ctrl.ts +++ b/public/app/features/dashboard/row/row_ctrl.ts @@ -44,7 +44,7 @@ export class DashRowCtrl { if (dropTarget) { dropTarget = this.dashboard.getPanelInfoById(dropTarget.id); // if draging new panel onto existing panel split it - if (dragObject.isNew) { + if (dragObject.panel.isNew) { dragObject.panel.span = dropTarget.panel.span = dropTarget.panel.span/2; // insert after dropTarget.row.panels.splice(dropTarget.index+1, 0, dragObject.panel); From 91431655808cd10acf7df4c9af702d95644cbda8 Mon Sep 17 00:00:00 2001 From: bergquist Date: Tue, 29 Nov 2016 17:41:06 +0100 Subject: [PATCH 05/12] tech(build): change windows build branch --- circle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circle.yml b/circle.yml index bbdcb05023c..a5a698e3988 100644 --- a/circle.yml +++ b/circle.yml @@ -23,7 +23,7 @@ test: - bash scripts/circle-test.sh deployment: - master: + v4.0.x: branch: v4.0.x owner: grafana commands: From a73bebbf3d08c733d081136d720c1b8580fe6a14 Mon Sep 17 00:00:00 2001 From: bergquist Date: Tue, 29 Nov 2016 18:18:44 +0100 Subject: [PATCH 06/12] tech(build): update publish script for 4.0.x release --- packaging/publish/publish.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packaging/publish/publish.sh b/packaging/publish/publish.sh index 291222a80e9..7619dd2e0f4 100755 --- a/packaging/publish/publish.sh +++ b/packaging/publish/publish.sh @@ -1,7 +1,6 @@ #! /usr/bin/env bash - -deb_ver=3.1.1-1470047149 -rpm_ver=3.1.1-1470047149 +deb_ver=4.0.0-1480439068 +rpm_ver=4.0.0-1480439068 wget https://grafanarel.s3.amazonaws.com/builds/grafana_${deb_ver}_amd64.deb From d3e47e50c1b6c8b090ef9f978343c1cf3117e86e Mon Sep 17 00:00:00 2001 From: fg2it Date: Wed, 30 Nov 2016 21:57:18 +0000 Subject: [PATCH 07/12] swap member declaration in StandardGauge to avoid problem with atomic on arm and x86-32 --- pkg/metrics/gauge.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/metrics/gauge.go b/pkg/metrics/gauge.go index 59758aa4ecb..cdae5ccff26 100644 --- a/pkg/metrics/gauge.go +++ b/pkg/metrics/gauge.go @@ -61,9 +61,10 @@ func (NilGauge) Value() int64 { return 0 } // StandardGauge is the standard implementation of a Gauge and uses the // sync/atomic package to manage a single int64 value. +// atomic needs 64-bit aligned memory which is ensure for first word type StandardGauge struct { - *MetricMeta value int64 + *MetricMeta } // Snapshot returns a read-only copy of the gauge. From bc69c8ef404b09416938dd8aec4b20995f3b8198 Mon Sep 17 00:00:00 2001 From: stuart nelson Date: Fri, 2 Dec 2016 15:39:28 +0100 Subject: [PATCH 08/12] Add transport cache for reverse proxy (#6776) * Add transport cache for reverse proxy * Use updated at in cache --- pkg/api/dataproxy.go | 29 +++++++++++++++ pkg/api/dataproxy_test.go | 76 ++++++++++++++++++++++++++++++++------- 2 files changed, 92 insertions(+), 13 deletions(-) diff --git a/pkg/api/dataproxy.go b/pkg/api/dataproxy.go index 803d966ee18..39de6911008 100644 --- a/pkg/api/dataproxy.go +++ b/pkg/api/dataproxy.go @@ -7,6 +7,7 @@ import ( "net/http" "net/http/httputil" "net/url" + "sync" "time" "github.com/grafana/grafana/pkg/api/cloudwatch" @@ -18,7 +19,29 @@ import ( "github.com/grafana/grafana/pkg/util" ) +type proxyTransportCache struct { + cache map[int64]cachedTransport + sync.Mutex +} + +type cachedTransport struct { + updated time.Time + + *http.Transport +} + +var ptc = proxyTransportCache{ + cache: make(map[int64]cachedTransport), +} + func DataProxyTransport(ds *m.DataSource) (*http.Transport, error) { + ptc.Lock() + defer ptc.Unlock() + + if t, present := ptc.cache[ds.Id]; present && ds.Updated.Equal(t.updated) { + return t.Transport, nil + } + transport := &http.Transport{ TLSClientConfig: &tls.Config{ InsecureSkipVerify: true, @@ -56,6 +79,12 @@ func DataProxyTransport(ds *m.DataSource) (*http.Transport, error) { } transport.TLSClientConfig.Certificates = []tls.Certificate{cert} } + + ptc.cache[ds.Id] = cachedTransport{ + Transport: transport, + updated: ds.Updated, + } + return transport, nil } diff --git a/pkg/api/dataproxy_test.go b/pkg/api/dataproxy_test.go index 5e6e62de0a3..50abf317e8a 100644 --- a/pkg/api/dataproxy_test.go +++ b/pkg/api/dataproxy_test.go @@ -4,6 +4,7 @@ import ( "net/http" "net/url" "testing" + "time" . "github.com/smartystreets/goconvey/convey" @@ -16,6 +17,7 @@ import ( func TestDataSourceProxy(t *testing.T) { Convey("When getting graphite datasource proxy", t, func() { + clearCache() ds := m.DataSource{Url: "htttp://graphite:8080", Type: m.DS_GRAPHITE} targetUrl, err := url.Parse(ds.Url) proxy := NewReverseProxy(&ds, "/render", targetUrl) @@ -38,6 +40,7 @@ func TestDataSourceProxy(t *testing.T) { }) Convey("When getting influxdb datasource proxy", t, func() { + clearCache() ds := m.DataSource{ Type: m.DS_INFLUXDB_08, Url: "http://influxdb:8083", @@ -65,38 +68,85 @@ func TestDataSourceProxy(t *testing.T) { }) }) + Convey("When caching a datasource proxy", t, func() { + clearCache() + ds := m.DataSource{ + Id: 1, + Url: "http://k8s:8001", + Type: "Kubernetes", + } + + t1, err := DataProxyTransport(&ds) + So(err, ShouldBeNil) + + t2, err := DataProxyTransport(&ds) + So(err, ShouldBeNil) + + Convey("Should be using the cached proxy", func() { + So(t2, ShouldEqual, t1) + }) + }) + Convey("When getting kubernetes datasource proxy", t, func() { + clearCache() setting.SecretKey = "password" json := simplejson.New() json.Set("tlsAuth", true) json.Set("tlsAuthWithCACert", true) + + t := time.Now() ds := m.DataSource{ - Url: "htttp://k8s:8001", - Type: "Kubernetes", - JsonData: json, - SecureJsonData: map[string][]byte{ - "tlsCACert": util.Encrypt([]byte(caCert), "password"), - "tlsClientCert": util.Encrypt([]byte(clientCert), "password"), - "tlsClientKey": util.Encrypt([]byte(clientKey), "password"), - }, + Url: "http://k8s:8001", + Type: "Kubernetes", + Updated: t.Add(-2 * time.Minute), } - targetUrl, err := url.Parse(ds.Url) - proxy := NewReverseProxy(&ds, "", targetUrl) - proxy.Transport, err = DataProxyTransport(&ds) + + transport, err := DataProxyTransport(&ds) So(err, ShouldBeNil) - transport, ok := proxy.Transport.(*http.Transport) + Convey("Should have no cert", func() { + So(transport.TLSClientConfig.InsecureSkipVerify, ShouldEqual, true) + }) + + ds.JsonData = json + ds.SecureJsonData = map[string][]byte{ + "tlsCACert": util.Encrypt([]byte(caCert), "password"), + "tlsClientCert": util.Encrypt([]byte(clientCert), "password"), + "tlsClientKey": util.Encrypt([]byte(clientKey), "password"), + } + ds.Updated = t.Add(-1 * time.Minute) + + transport, err = DataProxyTransport(&ds) + So(err, ShouldBeNil) Convey("Should add cert", func() { - So(ok, ShouldBeTrue) So(transport.TLSClientConfig.InsecureSkipVerify, ShouldEqual, false) So(len(transport.TLSClientConfig.Certificates), ShouldEqual, 1) }) + + ds.JsonData = nil + ds.SecureJsonData = map[string][]byte{} + ds.Updated = t + + transport, err = DataProxyTransport(&ds) + So(err, ShouldBeNil) + + Convey("Should remove cert", func() { + So(transport.TLSClientConfig.InsecureSkipVerify, ShouldEqual, true) + So(len(transport.TLSClientConfig.Certificates), ShouldEqual, 0) + }) }) } +func clearCache() { + ptc.Lock() + defer ptc.Unlock() + + ptc.cache = make(map[int64]cachedTransport) +} + const caCert string = `-----BEGIN CERTIFICATE----- MIIDATCCAemgAwIBAgIJAMQ5hC3CPDTeMA0GCSqGSIb3DQEBCwUAMBcxFTATBgNV BAMMDGNhLWs4cy1zdGhsbTAeFw0xNjEwMjcwODQyMjdaFw00NDAzMTQwODQyMjda From f7dced306783aad5b7984cbfcedf1426963eab40 Mon Sep 17 00:00:00 2001 From: bergquist Date: Fri, 2 Dec 2016 16:33:00 +0100 Subject: [PATCH 09/12] update to version 4.0.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b358c655c04..697c8a604fd 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "company": "Coding Instinct AB" }, "name": "grafana", - "version": "4.0.0", + "version": "4.0.1", "repository": { "type": "git", "url": "http://github.com/grafana/grafana.git" From 0403f53b6f71b3d0e5b717d6fe40c5226d8e7e91 Mon Sep 17 00:00:00 2001 From: bergquist Date: Fri, 2 Dec 2016 22:24:35 +0100 Subject: [PATCH 10/12] feat(webhook): adds alert rule message to webhook close #6807 --- pkg/services/alerting/notifiers/webhook.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/services/alerting/notifiers/webhook.go b/pkg/services/alerting/notifiers/webhook.go index 5a8163eecf3..44b5698efe5 100644 --- a/pkg/services/alerting/notifiers/webhook.go +++ b/pkg/services/alerting/notifiers/webhook.go @@ -58,6 +58,10 @@ func (this *WebhookNotifier) Notify(evalContext *alerting.EvalContext) error { bodyJSON.Set("imageUrl", evalContext.ImagePublicUrl) } + if evalContext.Rule.Message != "" { + bodyJSON.Set("message", evalContext.Rule.Message) + } + body, _ := bodyJSON.MarshalJSON() cmd := &m.SendWebhookSync{ From b81e97c99cdac7850d7033ad94dd99d527d1fe32 Mon Sep 17 00:00:00 2001 From: bergquist Date: Mon, 5 Dec 2016 10:44:31 +0100 Subject: [PATCH 11/12] webhook: adds json content-type closes #6822 --- pkg/services/notifications/webhook.go | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/pkg/services/notifications/webhook.go b/pkg/services/notifications/webhook.go index de1303d8131..ac46a43f294 100644 --- a/pkg/services/notifications/webhook.go +++ b/pkg/services/notifications/webhook.go @@ -6,7 +6,6 @@ import ( "fmt" "io/ioutil" "net/http" - "time" "golang.org/x/net/context/ctxhttp" @@ -22,8 +21,10 @@ type Webhook struct { HttpMethod string } -var webhookQueue chan *Webhook -var webhookLog log.Logger +var ( + webhookQueue chan *Webhook + webhookLog log.Logger +) func initWebhookQueue() { webhookLog = log.New("notifications.webhook") @@ -47,24 +48,22 @@ func processWebhookQueue() { func sendWebRequestSync(ctx context.Context, webhook *Webhook) error { webhookLog.Debug("Sending webhook", "url", webhook.Url, "http method", webhook.HttpMethod) - client := &http.Client{ - Timeout: time.Duration(10 * time.Second), - } - if webhook.HttpMethod == "" { webhook.HttpMethod = http.MethodPost } request, err := http.NewRequest(webhook.HttpMethod, webhook.Url, bytes.NewReader([]byte(webhook.Body))) - if webhook.User != "" && webhook.Password != "" { - request.Header.Add("Authorization", util.GetBasicAuthHeader(webhook.User, webhook.Password)) - } - if err != nil { return err } - resp, err := ctxhttp.Do(ctx, client, request) + request.Header.Add("Content-Type", "application/json") + request.Header.Add("User-Agent", "Grafana") + if webhook.User != "" && webhook.Password != "" { + request.Header.Add("Authorization", util.GetBasicAuthHeader(webhook.User, webhook.Password)) + } + + resp, err := ctxhttp.Do(ctx, http.DefaultClient, request) if err != nil { return err } @@ -73,11 +72,11 @@ func sendWebRequestSync(ctx context.Context, webhook *Webhook) error { return nil } + defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return err } - defer resp.Body.Close() webhookLog.Debug("Webhook failed", "statuscode", resp.Status, "body", string(body)) return fmt.Errorf("Webhook response status %v", resp.Status) From ab07667b6945b8d97cbc580737818a1a6accfbdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 5 Dec 2016 10:51:46 +0100 Subject: [PATCH 12/12] fix(rendering): minor fix for server side rendering when using non default http addr setting and non default domain setting, #6813 --- pkg/components/renderer/renderer.go | 8 ++++---- vendor/phantomjs/render.js | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/components/renderer/renderer.go b/pkg/components/renderer/renderer.go index 19d50e40af8..69a0b197ec8 100644 --- a/pkg/components/renderer/renderer.go +++ b/pkg/components/renderer/renderer.go @@ -35,12 +35,12 @@ func RenderToPng(params *RenderOpts) (string, error) { executable = executable + ".exe" } - localAddress := "localhost" + localDomain := "localhost" if setting.HttpAddr != setting.DEFAULT_HTTP_ADDR { - localAddress = setting.HttpAddr + localDomain = setting.HttpAddr } - url := fmt.Sprintf("%s://%s:%s/%s", setting.Protocol, localAddress, setting.HttpPort, params.Path) + url := fmt.Sprintf("%s://%s:%s/%s", setting.Protocol, localDomain, setting.HttpPort, params.Path) binPath, _ := filepath.Abs(filepath.Join(setting.PhantomDir, executable)) scriptPath, _ := filepath.Abs(filepath.Join(setting.PhantomDir, "render.js")) @@ -57,7 +57,7 @@ func RenderToPng(params *RenderOpts) (string, error) { "width=" + params.Width, "height=" + params.Height, "png=" + pngPath, - "domain=" + setting.Domain, + "domain=" + localDomain, "renderKey=" + renderKey, } diff --git a/vendor/phantomjs/render.js b/vendor/phantomjs/render.js index 2f62bfce955..b9039f1f482 100644 --- a/vendor/phantomjs/render.js +++ b/vendor/phantomjs/render.js @@ -22,7 +22,7 @@ phantom.addCookie({ 'name': 'renderKey', 'value': params.renderKey, - 'domain': 'localhost', + 'domain': params.domain, }); page.viewportSize = {