代码重构

pull/21/merge
ouqiang 2017-03-23 13:31:16 +08:00
parent 0f41bc6a65
commit e8351141c0
12 changed files with 148 additions and 41 deletions

View File

@ -43,7 +43,6 @@ func run(ctx *cli.Context) {
// 定时任务调度
func runScheduler() {
}
// 路由注册

View File

@ -3,4 +3,6 @@
; 默认不收集远程主机信息
gathering = explicit
; 默认模块
module_name = shell
module_name = shell
host_key_checking = false

0
conf/ansible_hosts.ini Normal file
View File

View File

@ -5,13 +5,23 @@ package models
type Host struct {
Id int16 `xorm:"smallint pk autoincr"`
Name string `xorm:"varchar(128) notnull"` // 主机名称
Alias string `xorm:"varchar(32) notnull default '' "` // 主机别名,仅用于后台显示
Port int `xorm:"notnull"` // 主机端口
Alias string `xorm:"varchar(32) notnull default '' "` // 主机别名
Username string `xorm:"varchar(32) notnull default '' "` // ssh 用户名
Password string `xorm:"varchar(64) notnull default ''"` // ssh 密码
Port int `xorm:"notnull default 22"` // 主机端口
LoginType LoginType `xorm:"tinyint notnull default 1"` // ssh登录方式 1:公钥认证 2:账号密码
Remark string `xorm:"varchar(512) notnull default '' "` // 备注
Page int `xorm:"-"`
PageSize int `xorm:"-"`
}
type LoginType int8;
const (
PublicKey = 1
UserPassword = 2
)
// 新增
func(host *Host) Create() (int64, error) {
return Db.Insert(host)

View File

@ -11,17 +11,18 @@ const (
SSH Protocol = 2
)
// 任务
type Task struct {
Id int `xorm:"int pk autoincr"`
Name string `xorm:"varchar(64) notnull"` // 任务名称
Spec string `xorm:"varchar(64) notnull"` // crontab 格式
Protocol Protocol `xorm:"tinyint notnull"` // 协议 1:http 2:ssh
Spec string `xorm:"varchar(64) notnull"` // crontab 时间格式
Protocol Protocol `xorm:"tinyint notnull"` // 协议 1:http 2:ssh
Type int8 `xorm:"tinyint notnull default 1"` // 任务类型 1: 定时任务 2: 延时任务
Command string `xorm:"varchar(512) notnull"` // URL地址或shell命令
Timeout int `xorm:"mediumint notnull default 0"` // 执行超时时间(单位秒)0不限制, 限制不能超过一周
SshHostGroup string `xorm:"varchar(512) notnull defalut '' "` // SSH主机名
Timeout int `xorm:"mediumint notnull default 0"` // 定时任务:执行超时时间(单位秒)0不限制 延时任务: 延时timeout秒后执行
SshHosts string `xorm:"varchar(512) notnull defalut '' "` // SSH主机名, host id逗号分隔
Remark string `xorm:"varchar(512) notnull default ''"` // 备注
Created time.Time `xorm:"datetime notnull created"` // 创建时间
Updated time.Time `xorm:"datetime updated"` // 更新时间
Deleted time.Time `xorm:"datetime deleted"` // 删除时间
Status Status `xorm:"tinyint notnull default 1"` // 状态 1:正常 0:停止
Page int `xorm:"-"`

View File

@ -4,17 +4,14 @@ import (
"time"
)
// 任务执行日志
type TaskLog struct{
Id int `xorm:"pk autoincr"`
Name string `xorm:"varchar(64) notnull"` // 任务名称
Protocol Protocol `xorm:"tinyint notnull "` // 协议
Command string `xorm:"varchar(512) notnull"` // URL或shell命令
Remark string `xorm:"varchar(512) notnull default ''"` // 备注
SshHosts string `xorm:"varchar(512) notnull default ''"`
Id int `xorm:"int pk autoincr"`
TaskId int `xorm:"int not null"` // 任务ID
StartTime time.Time `xorm:"datetime created"` // 开始执行时间
EndTime time.Time `xorm:"datetime updated"` // 执行完成(失败)时间
Status Status `xorm:"tinyint notnull default 1"` // 状态 1:执行中 2:执行完毕 0:执行失败
Result string `xorm:"varchar(65535) notnull defalut '' "`
Result string `xorm:"varchar(65535) notnull defalut '' "` // 执行结果
Page int `xorm:"-"`
PageSize int `xorm:"-"`
}

View File

@ -10,10 +10,10 @@ const PasswordSaltLength = 6;
// 用户model
type User struct {
Id int `xorm:"pk autoincr notnull "`
Name string `xorm:"varchar(32) notnull unique"`
Password string `xorm:"char(32) notnull "`
Salt string `xorm:"char(6) notnull "`
Email string `xorm:"varchar(50) notnull unique default '' "`
Name string `xorm:"varchar(32) notnull unique"` // 用户名
Password string `xorm:"char(32) notnull "` // 密码
Salt string `xorm:"char(6) notnull "` // 密码盐值
Email string `xorm:"varchar(50) notnull unique default '' "` // 邮箱
Created time.Time `xorm:"datetime notnull created"`
Updated time.Time `xorm:"datetime updated"`
Deleted time.Time `xorm:"datetime deleted"`

View File

@ -39,18 +39,26 @@ func(playbook *Playbook) AddHandler(handler Handler) {
/**
* ad-hoc
* hosts
* hosts
* module
* args
*/
func ExecCommand(hostPath string, module string, args... string) (output string, err error) {
if hostPath == "" || module == "" {
func ExecCommand(hosts string, module string, args... string) (output string, err error) {
if hosts== "" || module == "" {
err = errors.New("参数不完整")
return
}
commandArgs := []string{"-i", , hostPath, "-m", module}
hostFile, err := DefaultHosts.GetHostFile()
if err != nil {
return
}
defer func() {
os.Remove(hostFile)
}()
commandArgs := []string{hosts, "-i", hostFile, "-m", module}
if len(args) != 0 {
commandArgs = append(commandArgs, "-a", args...)
commandArgs = append(commandArgs, "-a")
commandArgs = append(commandArgs, args...)
}
output, err = utils.ExecShell("ansible", commandArgs...)
@ -58,32 +66,37 @@ func ExecCommand(hostPath string, module string, args... string) (output string,
}
// 执行playbook
func ExecPlaybook(hostPath string, playbook Playbook) (result string, err error) {
func ExecPlaybook(playbook Playbook) (result string, err error) {
data, err := yaml.Marshal([]Playbook{playbook})
if err != nil {
return
}
tmpFile, err := ioutil.TempFile(getTmpDir(), "playbook")
playbookFile, err := ioutil.TempFile(GetTmpDir(), "playbook")
if err != nil {
return
}
hostFile, err := DefaultHosts.GetHostFile()
if err != nil {
return
}
defer func() {
tmpFile.Close()
os.Remove(tmpFile.Name())
playbookFile.Close()
os.Remove(playbookFile.Name())
os.Remove(hostFile)
}()
_, err = tmpFile.Write(data)
_, err = playbookFile.Write(data)
if err != nil {
return
}
commandArgs := []string{"-i", hostPath, tmpFile.Name()}
commandArgs := []string{"-i", hostFile, playbookFile.Name()}
result, err = utils.ExecShell("ansible-playbook", commandArgs...)
return
}
// 判断 获取临时目录,默认/dev/shm
func getTmpDir() string {
func GetTmpDir() string {
dir := "/dev/shm"
_, err := os.Stat(dir)
if os.IsPermission(err) {

67
modules/ansible/host.go Normal file
View File

@ -0,0 +1,67 @@
package ansible
import (
"scheduler/models"
"sync"
"io/ioutil"
"bytes"
"strconv"
)
// 主机名
var DefaultHosts *Hosts
type Hosts struct {
sync.RWMutex
hosts []models.Host
}
func(h *Hosts) Get() []models.Host {
h.RLock()
defer h.RUnlock()
return h.hosts
}
func(h *Hosts) Set(hostsModel []models.Host) {
h.Lock()
defer h.Unlock()
h.hosts = hostsModel
}
// 获取hosts文件名
func(h *Hosts) GetHostFile() (filename string ,err error) {
buffer := bytes.Buffer{}
for _, hostModel := range(h.hosts) {
buffer.WriteString(strconv.Itoa(int(hostModel.Id)))
buffer.WriteString(" ansible_ssh_host=")
buffer.WriteString(hostModel.Name)
buffer.WriteString(" ansible_ssh_port=")
buffer.WriteString(strconv.Itoa(hostModel.Port))
buffer.WriteString(" ansible_ssh_user=")
buffer.WriteString(hostModel.Username)
if (hostModel.LoginType != models.PublicKey && hostModel.Password != "") {
buffer.WriteString(" ansible_ssh_pass=")
buffer.WriteString(hostModel.Password)
}
buffer.WriteString("\n")
}
tmpFile, err := ioutil.TempFile(GetTmpDir(), "host")
if err != nil {
return
}
defer func() {
tmpFile.Close()
}()
_, err = tmpFile.WriteString(buffer.String())
if err == nil {
filename = tmpFile.Name()
}
return
}

View File

@ -6,6 +6,7 @@ import (
"scheduler/models"
"runtime"
"scheduler/modules/utils"
"scheduler/modules/ansible"
)
var (
@ -14,8 +15,8 @@ var (
LogDir string // 日志目录
DataDir string // 数据目录存放session文件等
AppConfig string // 应用配置文件
AnsibleHosts string // ansible hosts文件
Installed bool // 应用是否安装过
CronTask crontask.CronTask // 定时任务
)
func init() {
@ -27,7 +28,8 @@ func init() {
ConfDir = AppDir + "/conf"
LogDir = AppDir + "/log"
DataDir = AppDir + "/data"
AppConfig = AppDir + "/app.ini"
AppConfig = ConfDir + "/app.ini"
AnsibleHosts = ConfDir + "/ansible_hosts.ini"
checkDirExists(ConfDir, LogDir, DataDir)
// ansible配置文件目录
os.Setenv("ANSIBLE_CONFIG", ConfDir)
@ -59,7 +61,7 @@ func CheckEnv() {
}
_, err = utils.ExecShell("ansible-playbook", "--version")
if err != nil {
panic("ansible-playbook not found")
panic(err)
}
}
@ -76,9 +78,16 @@ func CreateInstallLock() error {
// 初始化资源
func initResource() {
crontask.DefaultCronTask = crontask.CreateCronTask()
crontask.DefaultCronTask = crontask.NewCronTask()
models.Db = models.CreateDb(AppConfig)
ansible.DefaultHosts = &ansible.Hosts{}
hostModel := new(models.Host)
hosts, err := hostModel.List()
if err != nil {
utils.RecordLog(err)
} else {
ansible.DefaultHosts.Set(hosts)
}
}
// 检测目录是否存在

View File

@ -13,7 +13,7 @@ type CronTask struct {
tasks map[string]*cron.Cron
}
func CreateCronTask() *CronTask {
func NewCronTask() *CronTask {
return &CronTask {
sync.RWMutex{},
make(map[string]*cron.Cron),

View File

@ -53,9 +53,9 @@ type Handler interface {
Run(taskModel models.Task)
}
// HTTP任务
type HTTPHandler struct {}
// 执行HTTP任务
func(h *HTTPHandler) Run(taskModel models.Task) {
client := &http.Client{}
if (taskModel.Timeout > 0) {
@ -91,9 +91,18 @@ func(h *HTTPHandler) Run(taskModel models.Task) {
}
}
// SSH任务
type SSHHandler struct {}
// 执行SSH任务
func(ssh *SSHHandler) Run(taskModel models.Task) {
}
}
// 延时任务
type DelayHandler struct {}
func (handler *DelayHandler) Run(taskModel models.Task) {
}