Merge pull request #1018 in YUNIONIO/onecloud from ~QIUJIAN/onecloud:hotfix/qj-notify-with-template to release/2.6.0

* commit '44faf10bfd78537d97c921867e3316a216f59147':
  update influxdb in a more graceful manner
  removel logs
  minor fixes
  增加:补充完整通知消息功能
This commit is contained in:
邱剑
2019-02-11 23:04:17 +08:00
40 changed files with 620 additions and 67 deletions
@@ -0,0 +1 @@
您的云主机{{ .name }}的套餐类型已经更改为 CPU:{{ index .flavor_info "cpu" }}核,内存:{{ index .flavor_info "memory" }}M,数据盘:{{ index .flavor_info "datadisk" }}G,带宽: {{ index .flavor_info "ebw" }}M。
@@ -0,0 +1 @@
您的云主机{{ .name }}已经创建成功,服务器IP地址为{{ .ips }}{{ if .account }}初始帐号为{{ .account }}{{ end }}{{ if .keypair }}访问ssh密钥为{{ .keypair }}{{ end }}{{ if .password }}初始密码为{{ .password }}{{ end }}请使用{{ if .windows }}远程桌面连接器(RDC){{ else }}SSH{{ end }}或控制面板控制台访问云主机。
@@ -0,0 +1 @@
用户{{ .tenant }}的云主机{{ .name }}已经创建成功。
@@ -0,0 +1 @@
您的云主机{{ .name }}已经删除。
@@ -0,0 +1 @@
用户{{ .tenant }}的云主机{{ .name }}已经删除。
@@ -0,0 +1 @@
您的云主机{{ .name }}的系统盘已经重置成功,{{ if .account }}初始帐号为{{ .account }}{{ end }}{{ if .keypair }}访问密钥为{{ .keypair }}{{ end }}{{ if .password }}初始密码为{{ .password }}{{ end }}请使用{{ if .windows }}远程桌面连接器(RDC){{ else }}SSH{{ end }}或控制面板控制台访问云主机。
@@ -0,0 +1 @@
系统错误消息:{{ .msg }}({{ .created }})
@@ -0,0 +1 @@
系统警告消息:{{ .msg }}({{ .created }})
@@ -0,0 +1 @@
您的云主机{{ .name }}的套餐类型已经更改为 CPU:{{ index .flavor_info "cpu" }}核,内存:{{ index .flavor_info "memory" }}M,数据盘:{{ index .flavor_info "datadisk" }}G,带宽: {{ index .flavor_info "ebw" }}M。
@@ -0,0 +1 @@
云主机{{ .Name }}创建成功
@@ -0,0 +1 @@
用户{{ .tenant }}的云主机{{ .name }}已经创建成功
@@ -0,0 +1 @@
云主机{{ .name }}删除通知
@@ -0,0 +1 @@
用户{{ .tenant }}的云主机{{ .name }}已经删除
@@ -0,0 +1 @@
云主机{{ .name }}的系统盘重置成功
@@ -0,0 +1 @@
系统错误消息:{{ .msg }}({{ .created }})
@@ -0,0 +1 @@
系统警告消息:{{ .msg }}({{ .created }})
+21 -18
View File
@@ -1,10 +1,10 @@
package shell
import (
//"strings"
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/modules/notify"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
@@ -13,35 +13,38 @@ func init() {
/**
* 新建一个通知发送任务
*/
type NotificationCreateOptions struct {
UID string `help:"The user you wanna sent to (Keystone User ID)"`
CONTACTTYPE string `help:"User's contacts type, maybe email|mobile|dingtalk" choices:"email|mobile|dingtalk"`
CONTACTTYPE string `help:"User's contacts type, cloud be email|mobile|dingtalk|webconsole" choices:"email|mobile|dingtalk|webconsole"`
TOPIC string `help:"Title or topic of the notification"`
PRIORITY string `help:"Priority of the notification maybe normal|important|fatal" choices:"normal|important|fatal"`
MSG string `help:"The content of the notification"`
Remark string `help:"Remark or description of the notification"`
Group bool `help:"Send to group"`
Channel string `help:"User's contacts type, cloud be email|mobile|dingtalk|webconsole" choices:"email|mobile|dingtalk|webconsole"`
}
R(&NotificationCreateOptions{}, "notify", "Send a notification to sb", func(s *mcclient.ClientSession, args *NotificationCreateOptions) error {
params := jsonutils.NewDict()
msg := notify.SNotifyMessage{}
if args.Group {
params.Add(jsonutils.NewString(args.UID), "gid")
msg.Gid = args.UID
} else {
params.Add(jsonutils.NewString(args.UID), "uid")
}
params.Add(jsonutils.NewString(args.CONTACTTYPE), "contact_type")
params.Add(jsonutils.NewString(args.TOPIC), "topic")
params.Add(jsonutils.NewString(args.PRIORITY), "priority")
params.Add(jsonutils.NewString(args.MSG), "msg")
if len(args.Remark) > 0 {
params.Add(jsonutils.NewString(args.Remark), "remark")
msg.Uid = args.UID
}
notification, err := modules.Notifications.Create(s, params)
msg.ContactType = []notify.TNotifyChannel{notify.TNotifyChannel(args.CONTACTTYPE)}
for _, c := range args.Channel {
msg.ContactType = append(msg.ContactType, notify.TNotifyChannel(c))
}
msg.Topic = args.TOPIC
msg.Priority = notify.TNotifyPriority(args.PRIORITY)
msg.Msg = args.MSG
msg.Remark = args.Remark
err := notify.Notifications.Send(s, msg)
if err != nil {
return err
}
printObject(notification)
return nil
})
@@ -60,7 +63,7 @@ func init() {
params.Add(jsonutils.NewString(args.Remark), "remark")
}
notification, err := modules.Notifications.Put(s, args.ID, params)
notification, err := notify.Notifications.Put(s, args.ID, params)
if err != nil {
return err
}
@@ -75,12 +78,12 @@ func init() {
options.BaseListOptions
}
R(&NotificationListOptions{}, "notify-list", "List notification history", func(s *mcclient.ClientSession, args *NotificationListOptions) error {
result, err := modules.Notifications.List(s, nil)
result, err := notify.Notifications.List(s, nil)
if err != nil {
return err
}
printList(result, modules.Notifications.GetColumns(s))
printList(result, notify.Notifications.GetColumns(s))
return nil
})
+9
View File
@@ -0,0 +1,9 @@
package consts
var (
NotifyTemplateDir = "/opt/yunion/share/notify_templates"
)
func SetNotifyTemplateDir(dir string) {
NotifyTemplateDir = dir
}
+1 -1
View File
@@ -13,7 +13,7 @@ import (
type SResourceBase struct {
SModelBase
CreatedAt time.Time `nullable:"false" created_at:"true" get:"user" list:"user"`
CreatedAt time.Time `nullable:"false" created_at:"true" index:"true" get:"user" list:"user"`
UpdatedAt time.Time `nullable:"false" updated_at:"true" list:"user"`
UpdateVersion int `default:"0" nullable:"false" auto_version:"true" list:"user"`
DeletedAt time.Time ``
+13
View File
@@ -0,0 +1,13 @@
package notifyclient
const (
SYSTEM_ERROR = "SYSTEM_ERROR"
SYSTEM_WARNING = "SYSTEM_WARNING"
SERVER_CREATED = "SERVER_CREATED"
SERVER_CREATED_ADMIN = "SERVER_CREATED_ADMIN"
SERVER_DELETED = "SERVER_DELETED"
SERVER_DELETED_ADMIN = "SERVER_DELETED_ADMIN"
SERVER_REBUILD_ROOT = "SERVER_REBUILD_ROOT"
SERVER_CHANGE_FLAVOR = "SERVER_CHANGE_FLAVOR"
)
+144 -21
View File
@@ -1,35 +1,158 @@
package notifyclient
import (
"context"
"fmt"
"html/template"
"io/ioutil"
"path/filepath"
"strings"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/appsrv"
"yunion.io/x/onecloud/pkg/cloudcommon/consts"
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/onecloud/pkg/mcclient/modules/notify"
)
const (
PRIORITY_IMPORTANT = "important"
PRIORITY_CRITICAL = "fatal"
PRIORITY_NORMAL = "normal"
SERVER_CREATED = "SERVER_CREATED"
SERVER_CREATED_ADMIN = "SERVER_CREATED_ADMIN"
SERVER_DELETED = "SERVER_DELETED"
SERVER_DELETED_ADMIN = "SERVER_DELETED_ADMIN"
SERVER_REBUILD_ROOT = "SERVER_REBUILD_ROOT"
SERVER_CHANGE_FLAVOR = "SERVER_CHANGE_FLAVOR"
var (
templatesTable map[string]*template.Template
notifyClientWorkerMan *appsrv.SWorkerManager
)
var templateDir string
func SetTemplateDir(dir string) {
templateDir = dir
func init() {
notifyClientWorkerMan = appsrv.NewWorkerManager("NotifyClientWorkerManager", 1, 50, false)
templatesTable = make(map[string]*template.Template)
}
func NotifySystemError(id string, name string, status string, reason string) error {
log.Errorf("ID: %s Name %s Status %s REASON %s", id, name, status, reason)
return nil
func getTemplateString(topic string, contType string, channel notify.TNotifyChannel) ([]byte, error) {
if len(channel) > 0 {
path := filepath.Join(consts.NotifyTemplateDir, consts.GetServiceType(), contType, fmt.Sprintf("%s.%s", topic, string(channel)))
cont, err := ioutil.ReadFile(path)
if err == nil {
return cont, nil
}
}
path := filepath.Join(consts.NotifyTemplateDir, consts.GetServiceType(), contType, topic)
return ioutil.ReadFile(path)
}
func Notify(to string, event string, priority string, data jsonutils.JSONObject) error {
log.Infof("notify %s event %s priority %s data %s", to, event, priority, data)
return nil
func getTemplate(topic string, contType string) (*template.Template, error) {
key := fmt.Sprintf("%s.%s", topic, contType)
if _, ok := templatesTable[key]; !ok {
cont, err := getTemplateString(topic, contType, "")
if err != nil {
return nil, err
}
tmp, err := template.New(key).Parse(string(cont))
if err != nil {
return nil, err
}
templatesTable[key] = tmp
}
return templatesTable[key], nil
}
func getContent(topic string, contType string, data jsonutils.JSONObject) (string, error) {
tmpl, err := getTemplate(topic, contType)
if err != nil {
return "", err
}
buf := strings.Builder{}
err = tmpl.Execute(&buf, data.Interface())
if err != nil {
return "", err
}
// log.Debugf("notify.getContent %s %s %s %s", topic, contType, data, buf.String())
return buf.String(), nil
}
func Notify(recipientId string, isGroup bool, priority notify.TNotifyPriority, event string, data jsonutils.JSONObject) {
switch priority {
case notify.NotifyPriorityCritical:
NotifyCritical(recipientId, isGroup, event, data)
case notify.NotifyPriorityImportant:
NotifyImportant(recipientId, isGroup, event, data)
default:
NotifyNormal(recipientId, isGroup, event, data)
}
}
func RawNotify(recipientId string, isGroup bool, channels []notify.TNotifyChannel, priority notify.TNotifyPriority, event string, data jsonutils.JSONObject) {
log.Infof("notify %s event %s priority %s", recipientId, event, priority)
msg := notify.SNotifyMessage{}
if isGroup {
msg.Gid = recipientId
} else {
msg.Uid = recipientId
}
msg.Priority = priority
msg.ContactType = channels
topic, _ := getContent(event, "title", data)
if len(topic) == 0 {
topic = event
}
msg.Topic = topic
body, _ := getContent(event, "content", data)
if len(body) == 0 {
body = data.String()
}
msg.Msg = body
// log.Debugf("send notification %s %s", topic, body)
notifyClientWorkerMan.Run(func() {
s := auth.GetAdminSession(context.Background(), consts.GetRegion(), "")
notify.Notifications.Send(s, msg)
}, nil, nil)
}
func NotifyNormal(recipientId string, isGroup bool, event string, data jsonutils.JSONObject) {
RawNotify(recipientId, isGroup,
[]notify.TNotifyChannel{notify.NotifyByEmail, notify.NotifyByDingTalk},
notify.NotifyPriorityNormal,
event, data)
}
func NotifyImportant(recipientId string, isGroup bool, event string, data jsonutils.JSONObject) {
RawNotify(recipientId, isGroup,
[]notify.TNotifyChannel{notify.NotifyByEmail, notify.NotifyByDingTalk, notify.NotifyByMobile},
notify.NotifyPriorityImportant,
event, data)
}
func NotifyCritical(recipientId string, isGroup bool, event string, data jsonutils.JSONObject) {
RawNotify(recipientId, isGroup,
[]notify.TNotifyChannel{notify.NotifyByEmail, notify.NotifyByDingTalk, notify.NotifyByMobile},
notify.NotifyPriorityCritical,
event, data)
}
func SystemNotify(event string, data jsonutils.JSONObject) {
NotifyCritical(auth.AdminCredential().GetProjectId(), true, event, data)
}
func NotifyGeneralSystemError(data jsonutils.JSONObject) {
SystemNotify(SYSTEM_ERROR, data)
}
type sSystemErrorMsg struct {
Id string
Name string
Event string
Reason string
}
func NotifySystemError(idstr string, name string, event string, reason string) {
msg := sSystemErrorMsg{
Id: idstr,
Name: name,
Event: event,
Reason: reason,
}
SystemNotify(SYSTEM_ERROR, jsonutils.Marshal(msg))
}
func NotifySystemWarning(data jsonutils.JSONObject) {
SystemNotify(SYSTEM_WARNING, data)
}
@@ -0,0 +1,63 @@
package notifyclient
import (
"html/template"
"strings"
"testing"
"yunion.io/x/jsonutils"
)
func TestNotifyTemplate(t *testing.T) {
cases := []struct {
template string
data interface{}
want string
}{
{
`云主机{{ .name }}创建成功`,
struct {
Name string
}{
Name: "testsrv-1",
},
`云主机testsrv-1创建成功`,
},
{
`您的云主机{{ .name }}已经创建成功,服务器IP地址为{{ .ips }}{{ if .account }}初始帐号为{{ .account }}{{ end }}{{ if .keypair }}访问密钥为{{ .keypair }}{{ end }}{{ if len .password }}初始密码为{{ .password }}{{ end }}请使用{{ if .windows }}远程桌面连接器(RDC){{ else }}SSH{{ end }}或控制面板控制台访问云主机。`,
struct {
Name string
Ips string
Account string
Keypair string
Password string
Windows bool
}{
Name: "testsrv-1",
Ips: "10.168.222.23",
Account: "root",
Password: "1234567",
Windows: false,
},
`您的云主机testsrv-1已经创建成功,服务器IP地址为10.168.222.23,初始帐号为root,初始密码为1234567,请使用SSH或控制面板控制台访问云主机。`,
},
}
for _, c := range cases {
temp, err := template.New("template").Parse(c.template)
if err != nil {
t.Errorf("parse template %s fail %s", c.template, err)
} else {
strBuild := strings.Builder{}
jsonData := jsonutils.Marshal(c.data)
t.Logf("jsonData: %s", jsonData)
err = temp.Execute(&strBuild, jsonData.Interface())
if err != nil {
t.Error("execute template fail %s", err)
} else {
if strBuild.String() != c.want {
t.Error("fail: got %s want %s", strBuild.String(), c.want)
}
}
}
}
}
+7 -6
View File
@@ -28,6 +28,7 @@ import (
"yunion.io/x/onecloud/pkg/compute/options"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/modules/notify"
"yunion.io/x/onecloud/pkg/util/httputils"
"yunion.io/x/onecloud/pkg/util/logclient"
"yunion.io/x/onecloud/pkg/util/seclib2"
@@ -508,15 +509,15 @@ func (self *SGuest) StartGuestDeployTask(ctx context.Context, userCred mcclient.
return nil
}
func (self *SGuest) NotifyServerEvent(event string, priority string, loginInfo bool) error {
func (self *SGuest) NotifyServerEvent(event string, priority notify.TNotifyPriority, loginInfo bool) {
meta, err := self.GetAllMetadata(nil)
if err != nil {
return err
return
}
kwargs := jsonutils.NewDict()
kwargs.Add(jsonutils.NewString(self.Name), "name")
if loginInfo {
kwargs.Add(jsonutils.NewStringArray(self.getNotifyIps()), "ips")
kwargs.Add(jsonutils.NewString(self.getNotifyIps()), "ips")
osName := meta["os_name"]
if osName == "Windows" {
kwargs.Add(jsonutils.JSONTrue, "windows")
@@ -538,10 +539,10 @@ func (self *SGuest) NotifyServerEvent(event string, priority string, loginInfo b
}
}
}
return notifyclient.Notify(self.ProjectId, event, priority, kwargs)
notifyclient.Notify(self.ProjectId, true, priority, event, kwargs)
}
func (self *SGuest) NotifyAdminServerEvent(ctx context.Context, event string, priority string) error {
func (self *SGuest) NotifyAdminServerEvent(ctx context.Context, event string, priority notify.TNotifyPriority) {
kwargs := jsonutils.NewDict()
kwargs.Add(jsonutils.NewString(self.Name), "name")
tc, _ := self.GetTenantCache(ctx)
@@ -550,7 +551,7 @@ func (self *SGuest) NotifyAdminServerEvent(ctx context.Context, event string, pr
} else {
kwargs.Add(jsonutils.NewString(self.ProjectId), "tenant")
}
return notifyclient.Notify(options.Options.NotifyAdminUser, event, priority, kwargs)
notifyclient.Notify(options.Options.NotifyAdminUser, true, priority, event, kwargs)
}
func (self *SGuest) StartGuestStopTask(ctx context.Context, userCred mcclient.TokenCredential, isForce bool, parentTaskId string) error {
+2 -2
View File
@@ -1560,13 +1560,13 @@ func (self *SGuest) getKeypairName() string {
return ""
}
func (self *SGuest) getNotifyIps() []string {
func (self *SGuest) getNotifyIps() string {
ips := self.getRealIPs()
vips := self.getVirtualIPs()
if vips != nil {
ips = append(ips, vips...)
}
return ips
return strings.Join(ips, ",")
}
func (self *SGuest) getRealIPs() []string {
+42
View File
@@ -0,0 +1,42 @@
package service
import (
"fmt"
"yunion.io/x/onecloud/pkg/compute/options"
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/onecloud/pkg/util/influxdb"
)
func setInfluxdbRetentionPolicy() error {
urls, err := auth.GetServiceURLs("influxdb", options.Options.Region, "", "internal")
if err != nil {
return err
}
for _, url := range urls {
err = setInfluxdbRetentionPolicyForUrl(url)
if err != nil {
return err
}
}
return nil
}
func setInfluxdbRetentionPolicyForUrl(url string) error {
db := influxdb.NewInfluxdb(url)
err := db.SetDatabase("telegraf")
if err != nil {
return err
}
rp := influxdb.SRetentionPolicy{
Name: "30day_only",
Duration: fmt.Sprintf("%dd", options.Options.MetricsRetentionDays),
ReplicaN: 1,
Default: true,
}
err = db.SetRetentionPolicy(rp)
if err != nil {
return err
}
return nil
}
+5
View File
@@ -60,6 +60,11 @@ func StartService() {
log.Errorf("InitDB fail: %s", err)
}
err = setInfluxdbRetentionPolicy()
if err != nil {
log.Errorf("setInfluxdbRetentionPolicy fail: %s", err)
}
cron := cronman.GetCronJobManager(true)
cron.AddJob1("CleanPendingDeleteServers", time.Duration(opts.PendingDeleteCheckSeconds)*time.Second, models.GuestManager.CleanPendingDeleteServers)
cron.AddJob1("CleanPendingDeleteDisks", time.Duration(opts.PendingDeleteCheckSeconds)*time.Second, models.DiskManager.CleanPendingDeleteDisks)
+3 -2
View File
@@ -12,6 +12,7 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/notifyclient"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/mcclient/modules/notify"
"yunion.io/x/onecloud/pkg/util/logclient"
)
@@ -100,8 +101,8 @@ func (self *GuestCreateTask) OnDeployGuestDescComplete(ctx context.Context, obj
}
func (self *GuestCreateTask) notifyServerCreated(ctx context.Context, guest *models.SGuest) {
guest.NotifyServerEvent(notifyclient.SERVER_CREATED, notifyclient.PRIORITY_IMPORTANT, true)
guest.NotifyAdminServerEvent(ctx, notifyclient.SERVER_CREATED_ADMIN, notifyclient.PRIORITY_IMPORTANT)
guest.NotifyServerEvent(notifyclient.SERVER_CREATED, notify.NotifyPriorityImportant, true)
guest.NotifyAdminServerEvent(ctx, notifyclient.SERVER_CREATED_ADMIN, notify.NotifyPriorityImportant)
}
func (self *GuestCreateTask) OnDeployGuestDescCompleteFailed(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
+5 -3
View File
@@ -13,6 +13,7 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/notifyclient"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/compute/options"
"yunion.io/x/onecloud/pkg/mcclient/modules/notify"
"yunion.io/x/onecloud/pkg/util/logclient"
)
@@ -252,11 +253,12 @@ func (self *GuestDeleteTask) OnGuestDeleteComplete(ctx context.Context, obj db.I
}
func (self *GuestDeleteTask) DeleteGuest(ctx context.Context, guest *models.SGuest) {
isPendingDeleted := guest.PendingDeleted
guest.RealDelete(ctx, self.UserCred)
guest.RemoveAllMetadata(ctx, self.UserCred)
db.OpsLog.LogEvent(guest, db.ACT_DELOCATE, nil, self.UserCred)
logclient.AddActionLog(guest, logclient.ACT_DELETE, nil, self.UserCred, true)
if !guest.IsSystem && !guest.PendingDeleted {
if !guest.IsSystem && !isPendingDeleted {
self.NotifyServerDeleted(ctx, guest)
}
models.HostManager.ClearSchedDescCache(guest.HostId)
@@ -264,6 +266,6 @@ func (self *GuestDeleteTask) DeleteGuest(ctx context.Context, guest *models.SGue
}
func (self *GuestDeleteTask) NotifyServerDeleted(ctx context.Context, guest *models.SGuest) {
guest.NotifyServerEvent(notifyclient.SERVER_DELETED, notifyclient.PRIORITY_IMPORTANT, false)
guest.NotifyAdminServerEvent(ctx, notifyclient.SERVER_DELETED_ADMIN, notifyclient.PRIORITY_IMPORTANT)
guest.NotifyServerEvent(notifyclient.SERVER_DELETED, notify.NotifyPriorityImportant, false)
guest.NotifyAdminServerEvent(ctx, notifyclient.SERVER_DELETED_ADMIN, notify.NotifyPriorityImportant)
}
+2 -1
View File
@@ -11,6 +11,7 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/notifyclient"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/mcclient/modules/notify"
"yunion.io/x/onecloud/pkg/util/logclient"
)
@@ -148,7 +149,7 @@ func (self *GuestRebuildRootTask) OnRebuildAllDisksComplete(ctx context.Context,
}
}
db.OpsLog.LogEvent(guest, db.ACT_REBUILD_ROOT, "", self.UserCred)
guest.NotifyServerEvent(notifyclient.SERVER_REBUILD_ROOT, notifyclient.PRIORITY_IMPORTANT, true)
guest.NotifyServerEvent(notifyclient.SERVER_REBUILD_ROOT, notify.NotifyPriorityImportant, true)
self.SetStage("OnSyncStatusComplete", nil)
guest.StartSyncstatus(ctx, self.UserCred, self.GetTaskId())
}
+1
View File
@@ -0,0 +1 @@
package diskhandlers // import "yunion.io/x/onecloud/pkg/hostman/diskhandlers"
+1
View File
@@ -0,0 +1 @@
package guesthandlers // import "yunion.io/x/onecloud/pkg/hostman/guesthandlers"
+1
View File
@@ -55,6 +55,7 @@ func (s *STelegraf) GetConfig(kwargs map[string]interface{}) string {
conf += "[[outputs.influxdb]]\n"
conf += fmt.Sprintf(" urls = [%s]\n", strings.Join(urls, ", "))
conf += fmt.Sprintf(" database = \"%s\"\n", tdb)
conf += " retention_policy = \"autogen\"\n"
conf += " insecure_skip_verify = true\n"
conf += "\n"
}
-13
View File
@@ -1,13 +0,0 @@
package modules
var (
Notifications ResourceManager
)
func init() {
Notifications = NewNotifyManager("notification", "notifications",
[]string{"id", "uid", "contact_type", "topic", "priority", "msg", "received_at", "send_by", "status", "create_at", "update_at", "delete_at", "create_by", "update_by", "delete_by", "is_deleted", "remark"},
[]string{})
register(&Notifications)
}
+16
View File
@@ -0,0 +1,16 @@
package notify
type TNotifyPriority string
type TNotifyChannel string
const (
NotifyPriorityImportant = TNotifyPriority("important")
NotifyPriorityCritical = TNotifyPriority("fatal")
NotifyPriorityNormal = TNotifyPriority("normal")
NotifyByEmail = TNotifyChannel("email")
NotifyByMobile = TNotifyChannel("mobile")
NotifyByDingTalk = TNotifyChannel("dingtalk")
NotifyByWebConsole = TNotifyChannel("webconsole")
)
+1
View File
@@ -0,0 +1 @@
package notify // import "yunion.io/x/onecloud/pkg/mcclient/modules/notify"
@@ -0,0 +1,41 @@
package notify
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/modules"
)
var (
Notifications NotificationManager
)
type SNotifyMessage struct {
Uid string `json:"uid,omitempty"`
Gid string `json:"uid,omitempty"`
ContactType []TNotifyChannel `json:"contact_type,omitempty"`
Topic string `json:"topic,omitempty"`
Priority TNotifyPriority `json:"priority,omitempty"`
Msg string `json:"msg,omitempty"`
Remark string `json:"remark,omitempty"`
}
type NotificationManager struct {
modules.ResourceManager
}
func (manager *NotificationManager) Send(s *mcclient.ClientSession, msg SNotifyMessage) error {
_, err := manager.Create(s, jsonutils.Marshal(&msg))
return err
}
func init() {
Notifications = NotificationManager{
modules.NewNotifyManager("notification", "notifications",
[]string{"id", "uid", "contact_type", "topic", "priority", "msg", "received_at", "send_by", "status", "create_at", "update_at", "delete_at", "create_by", "update_by", "delete_by", "is_deleted", "remark"},
[]string{}),
}
modules.Register(&Notifications)
}
@@ -0,0 +1,22 @@
package notify
import (
"testing"
"yunion.io/x/jsonutils"
)
func TestNotificationManager(t *testing.T) {
msg := SNotifyMessage{
Uid: "testuser",
ContactType: []TNotifyChannel{
NotifyByEmail, NotifyByWebConsole,
},
Topic: "test message",
Priority: NotifyPriorityNormal,
Msg: "This is a test message. Yey!!",
Remark: "Yunion",
}
msgJson := jsonutils.Marshal(msg)
t.Logf("msg: %s", msgJson)
}
+1
View File
@@ -0,0 +1 @@
package influxdb // import "yunion.io/x/onecloud/pkg/util/influxdb"
+173
View File
@@ -0,0 +1,173 @@
package influxdb
import (
"context"
"fmt"
"net/http"
"net/url"
"strings"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/utils"
"yunion.io/x/onecloud/pkg/util/httputils"
)
type SInfluxdb struct {
accessUrl string
client *http.Client
dbName string
}
func NewInfluxdb(accessUrl string) *SInfluxdb {
inst := SInfluxdb{
accessUrl: accessUrl,
client: httputils.GetDefaultClient(),
}
return &inst
}
type dbResult struct {
Name string
Columns []string
Values [][]jsonutils.JSONObject
}
func (db *SInfluxdb) query(sql string) ([][]dbResult, error) {
nurl := fmt.Sprintf("%s/query?q=%s", db.accessUrl, url.QueryEscape(sql))
_, body, err := httputils.JSONRequest(db.client, context.Background(), "POST", nurl, nil, nil, false)
if err != nil {
return nil, err
}
log.Debugf("influx query: %s %s", db.accessUrl, body)
results, err := body.GetArray("results")
if err != nil {
return nil, err
}
rets := make([][]dbResult, len(results))
for i := range results {
series, err := results[i].Get("series")
if err == nil {
ret := make([]dbResult, 0)
err = series.Unmarshal(&ret)
if err != nil {
return nil, err
}
rets[i] = ret
}
}
return rets, nil
}
func (db *SInfluxdb) SetDatabase(dbName string) error {
dbs, err := db.GetDatabases()
if err != nil {
return err
}
if !utils.IsInStringArray(dbName, dbs) {
err = db.CreateDatabase(dbName)
if err != nil {
return err
}
return nil
}
db.dbName = dbName
return nil
}
func (db *SInfluxdb) CreateDatabase(dbName string) error {
_, err := db.query(fmt.Sprintf("CREATE DATABASE %s", dbName))
if err != nil {
return err
}
return nil
}
func (db *SInfluxdb) GetDatabases() ([]string, error) {
results, err := db.query("SHOW DATABASES")
if err != nil {
return nil, err
}
res := results[0][0]
ret := make([]string, len(res.Values))
for i := range res.Values {
ret[i], _ = res.Values[i][0].GetString()
}
return ret, nil
}
type SRetentionPolicy struct {
Name string
Duration string
ShardGroupDuration string
ReplicaN int
Default bool
}
func (rp *SRetentionPolicy) String(dbName string) string {
var buf strings.Builder
buf.WriteString("RETENTION POLICY \"")
buf.WriteString(rp.Name)
buf.WriteString("\" ON \"")
buf.WriteString(dbName)
buf.WriteString("\" DURATION ")
buf.WriteString(rp.Duration)
buf.WriteString(fmt.Sprintf(" REPLICATION %d", rp.ReplicaN))
if len(rp.ShardGroupDuration) > 0 {
buf.WriteString(fmt.Sprintf(" SHARD DURATION %s", rp.ShardGroupDuration))
}
if rp.Default {
buf.WriteString(" DEFAULT")
}
return buf.String()
}
func (db *SInfluxdb) GetRetentionPolicies() ([]SRetentionPolicy, error) {
results, err := db.query(fmt.Sprintf("SHOW RETENTION POLICIES ON %s", db.dbName))
if err != nil {
return nil, err
}
res := results[0][0]
ret := make([]SRetentionPolicy, len(res.Values))
for i := range res.Values {
tmpDict := jsonutils.NewDict()
for j := range res.Columns {
tmpDict.Add(res.Values[i][j], res.Columns[j])
}
err = tmpDict.Unmarshal(&ret[i])
if err != nil {
return nil, err
}
}
return ret, nil
}
func (db *SInfluxdb) CreateRetentionPolicy(rp SRetentionPolicy) error {
_, err := db.query(fmt.Sprintf("CREATE %s", rp.String(db.dbName)))
return err
}
func (db *SInfluxdb) AlterRetentionPolicy(rp SRetentionPolicy) error {
_, err := db.query(fmt.Sprintf("ALTER %s", rp.String(db.dbName)))
return err
}
func (db *SInfluxdb) SetRetentionPolicy(rp SRetentionPolicy) error {
rps, err := db.GetRetentionPolicies()
if err != nil {
return err
}
find := false
for i := range rps {
if rps[i].Name == rp.Name {
find = true
break
}
}
if find {
return db.AlterRetentionPolicy(rp)
} else {
return db.CreateRetentionPolicy(rp)
}
}
+30
View File
@@ -0,0 +1,30 @@
package influxdb
import (
"testing"
)
func TestInfluxdb(t *testing.T) {
url := "https://192.168.222.171:8086"
db := NewInfluxdb(url)
err := db.SetDatabase("telegraf1")
if err != nil {
t.Fatalf("GetDatabases: %s", err)
}
rp := SRetentionPolicy{
Name: "30days",
Duration: "30d",
ReplicaN: 1,
Default: true,
}
err = db.SetRetentionPolicy(rp)
if err != nil {
t.Fatalf("SetRetentPolicy: %s", err)
}
rps, err := db.GetRetentionPolicies()
if err != nil {
t.Fatalf("GetRentionPolicies %s", err)
}
t.Logf("%#v", rps)
}