Provisioning: Interpolate env vars in provisioning files (#16499)

* Add value types with custom unmarshalling logic

* Add env support for notifications config

* Use env vars in json data tests for values

* Add some more complexities to value tests

* Update comment with example usage

* Set env directly in the tests, removing patching

* Update documentation

* Add env var to the file reader tests

* Add raw value

* Post merge fixes

* Add comment
This commit is contained in:
Andrej Ocenas
2019-04-24 15:39:47 +02:00
committed by GitHub
parent eb8af01a8a
commit fcebd713a5
14 changed files with 598 additions and 141 deletions
@@ -131,39 +131,6 @@ func (dc *NotificationProvisioner) mergeNotifications(notificationToMerge []*not
return nil
}
func (cfg *notificationsAsConfig) mapToNotificationFromConfig() *notificationsAsConfig {
r := &notificationsAsConfig{}
if cfg == nil {
return r
}
for _, notification := range cfg.Notifications {
r.Notifications = append(r.Notifications, &notificationFromConfig{
Uid: notification.Uid,
OrgId: notification.OrgId,
OrgName: notification.OrgName,
Name: notification.Name,
Type: notification.Type,
IsDefault: notification.IsDefault,
Settings: notification.Settings,
DisableResolveMessage: notification.DisableResolveMessage,
Frequency: notification.Frequency,
SendReminder: notification.SendReminder,
})
}
for _, notification := range cfg.DeleteNotifications {
r.DeleteNotifications = append(r.DeleteNotifications, &deleteNotificationConfig{
Uid: notification.Uid,
OrgId: notification.OrgId,
OrgName: notification.OrgName,
Name: notification.Name,
})
}
return r
}
func (dc *NotificationProvisioner) applyChanges(configPath string) error {
configs, err := dc.cfgProvider.readConfig(configPath)
if err != nil {
@@ -63,7 +63,7 @@ func (cr *configReader) parseNotificationConfig(path string, file os.FileInfo) (
return nil, err
}
var cfg *notificationsAsConfig
var cfg *notificationsAsConfigV0
err = yaml.Unmarshal(yamlFile, &cfg)
if err != nil {
return nil, err
@@ -1,6 +1,7 @@
package notifiers
import (
"os"
"testing"
"github.com/grafana/grafana/pkg/log"
@@ -43,8 +44,10 @@ func TestNotificationAsConfig(t *testing.T) {
})
Convey("Can read correct properties", func() {
_ = os.Setenv("TEST_VAR", "default")
cfgProvifer := &configReader{log: log.New("test logger")}
cfg, err := cfgProvifer.readConfig(correct_properties)
_ = os.Unsetenv("TEST_VAR")
if err != nil {
t.Fatalf("readConfig return an error %v", err)
}
@@ -1,5 +1,5 @@
notifiers:
- name: default-slack-notification
- name: $TEST_VAR-slack-notification
type: slack
uid: notifier1
org_id: 2
@@ -39,4 +39,4 @@ delete_notifiers:
org_id: 0
uid: "notifier3"
- name: Deleted notification with whitespaces in name
uid: "notifier4"
uid: "notifier4"
+83 -17
View File
@@ -1,30 +1,61 @@
package notifiers
import "github.com/grafana/grafana/pkg/components/simplejson"
import (
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/services/provisioning/values"
)
// notificationsAsConfig is normalized data object for notifications config data. Any config version should be mappable
// to this type.
type notificationsAsConfig struct {
Notifications []*notificationFromConfig `json:"notifiers" yaml:"notifiers"`
DeleteNotifications []*deleteNotificationConfig `json:"delete_notifiers" yaml:"delete_notifiers"`
Notifications []*notificationFromConfig
DeleteNotifications []*deleteNotificationConfig
}
type deleteNotificationConfig struct {
Uid string `json:"uid" yaml:"uid"`
Name string `json:"name" yaml:"name"`
OrgId int64 `json:"org_id" yaml:"org_id"`
OrgName string `json:"org_name" yaml:"org_name"`
Uid string
Name string
OrgId int64
OrgName string
}
type notificationFromConfig struct {
Uid string `json:"uid" yaml:"uid"`
OrgId int64 `json:"org_id" yaml:"org_id"`
OrgName string `json:"org_name" yaml:"org_name"`
Name string `json:"name" yaml:"name"`
Type string `json:"type" yaml:"type"`
SendReminder bool `json:"send_reminder" yaml:"send_reminder"`
DisableResolveMessage bool `json:"disable_resolve_message" yaml:"disable_resolve_message"`
Frequency string `json:"frequency" yaml:"frequency"`
IsDefault bool `json:"is_default" yaml:"is_default"`
Settings map[string]interface{} `json:"settings" yaml:"settings"`
Uid string
OrgId int64
OrgName string
Name string
Type string
SendReminder bool
DisableResolveMessage bool
Frequency string
IsDefault bool
Settings map[string]interface{}
}
// notificationsAsConfigV0 is mapping for zero version configs. This is mapped to its normalised version.
type notificationsAsConfigV0 struct {
Notifications []*notificationFromConfigV0 `json:"notifiers" yaml:"notifiers"`
DeleteNotifications []*deleteNotificationConfigV0 `json:"delete_notifiers" yaml:"delete_notifiers"`
}
type deleteNotificationConfigV0 struct {
Uid values.StringValue `json:"uid" yaml:"uid"`
Name values.StringValue `json:"name" yaml:"name"`
OrgId values.Int64Value `json:"org_id" yaml:"org_id"`
OrgName values.StringValue `json:"org_name" yaml:"org_name"`
}
type notificationFromConfigV0 struct {
Uid values.StringValue `json:"uid" yaml:"uid"`
OrgId values.Int64Value `json:"org_id" yaml:"org_id"`
OrgName values.StringValue `json:"org_name" yaml:"org_name"`
Name values.StringValue `json:"name" yaml:"name"`
Type values.StringValue `json:"type" yaml:"type"`
SendReminder values.BoolValue `json:"send_reminder" yaml:"send_reminder"`
DisableResolveMessage values.BoolValue `json:"disable_resolve_message" yaml:"disable_resolve_message"`
Frequency values.StringValue `json:"frequency" yaml:"frequency"`
IsDefault values.BoolValue `json:"is_default" yaml:"is_default"`
Settings values.JSONValue `json:"settings" yaml:"settings"`
}
func (notification notificationFromConfig) SettingsToJson() *simplejson.Json {
@@ -36,3 +67,38 @@ func (notification notificationFromConfig) SettingsToJson() *simplejson.Json {
}
return settings
}
// mapToNotificationFromConfig maps config syntax to normalized notificationsAsConfig object. Every version
// of the config syntax should have this function.
func (cfg *notificationsAsConfigV0) mapToNotificationFromConfig() *notificationsAsConfig {
r := &notificationsAsConfig{}
if cfg == nil {
return r
}
for _, notification := range cfg.Notifications {
r.Notifications = append(r.Notifications, &notificationFromConfig{
Uid: notification.Uid.Value(),
OrgId: notification.OrgId.Value(),
OrgName: notification.OrgName.Value(),
Name: notification.Name.Value(),
Type: notification.Type.Value(),
IsDefault: notification.IsDefault.Value(),
Settings: notification.Settings.Value(),
DisableResolveMessage: notification.DisableResolveMessage.Value(),
Frequency: notification.Frequency.Value(),
SendReminder: notification.SendReminder.Value(),
})
}
for _, notification := range cfg.DeleteNotifications {
r.DeleteNotifications = append(r.DeleteNotifications, &deleteNotificationConfig{
Uid: notification.Uid.Value(),
OrgId: notification.OrgId.Value(),
OrgName: notification.OrgName.Value(),
Name: notification.Name.Value(),
})
}
return r
}