mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-08-31 01:35:56 +08:00
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:
+1
@@ -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 }}或控制面板控制台访问云主机。
|
||||
+1
@@ -0,0 +1 @@
|
||||
用户{{ .tenant }}的云主机{{ .name }}已经创建成功。
|
||||
@@ -0,0 +1 @@
|
||||
您的云主机{{ .name }}已经删除。
|
||||
+1
@@ -0,0 +1 @@
|
||||
用户{{ .tenant }}的云主机{{ .name }}已经删除。
|
||||
+1
@@ -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 }})
|
||||
@@ -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
|
||||
})
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package consts
|
||||
|
||||
var (
|
||||
NotifyTemplateDir = "/opt/yunion/share/notify_templates"
|
||||
)
|
||||
|
||||
func SetNotifyTemplateDir(dir string) {
|
||||
NotifyTemplateDir = dir
|
||||
}
|
||||
@@ -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 ``
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
package diskhandlers // import "yunion.io/x/onecloud/pkg/hostman/diskhandlers"
|
||||
@@ -0,0 +1 @@
|
||||
package guesthandlers // import "yunion.io/x/onecloud/pkg/hostman/guesthandlers"
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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")
|
||||
)
|
||||
@@ -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)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
package influxdb // import "yunion.io/x/onecloud/pkg/util/influxdb"
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
Reference in New Issue
Block a user