代码格式化

pull/21/merge
ouqiang 2017-04-02 10:19:52 +08:00
parent 7e5b84c320
commit 16582a5775
18 changed files with 272 additions and 286 deletions

View File

@ -1,27 +1,28 @@
package cmd
import (
"github.com/urfave/cli"
"gopkg.in/macaron.v1"
"github.com/go-macaron/csrf"
"github.com/go-macaron/gzip"
"github.com/go-macaron/session"
"github.com/go-macaron/csrf"
"github.com/ouqiang/cron-scheduler/modules/app"
"github.com/ouqiang/cron-scheduler/routers"
"github.com/urfave/cli"
"gopkg.in/macaron.v1"
)
// web服务器默认端口
const DefaultPort = 5920
// 静态文件目录
const StaticDir = "public"
var CmdWeb = cli.Command{
Name: "server",
Usage: "start scheduler web server",
Name: "server",
Usage: "start scheduler web server",
Action: run,
Flags: []cli.Flag{
cli.IntFlag{
Name: "port,p",
Name: "port,p",
Value: DefaultPort,
Usage: "bind port number",
},
@ -40,13 +41,13 @@ func run(ctx *cli.Context) {
}
// 中间件注册
func registerMiddleware(m *macaron.Macaron) {
func registerMiddleware(m *macaron.Macaron) {
m.Use(macaron.Logger())
m.Use(macaron.Recovery())
m.Use(gzip.Gziper())
m.Use(macaron.Static(StaticDir))
m.Use(macaron.Renderer(macaron.RenderOptions{
Directory: "templates",
Directory: "templates",
Extensions: []string{".html"},
// 模板语法分隔符,默认为 ["{{", "}}"]
Delims: macaron.Delims{"{{{", "}}}"},
@ -64,7 +65,7 @@ func registerMiddleware(m *macaron.Macaron) {
// 解析端口
func parsePort(ctx *cli.Context) int {
var port int
if (ctx.IsSet("port")) {
if ctx.IsSet("port") {
port = ctx.Int("port")
}
if port <= 0 || port >= 65535 {
@ -72,4 +73,4 @@ func parsePort(ctx *cli.Context) int {
}
return port
}
}

View File

@ -1,30 +1,29 @@
package models
// 主机
type Host struct {
Id int16 `xorm:"smallint pk autoincr"`
Name string `xorm:"varchar(128) 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:"-"`
Id int16 `xorm:"smallint pk autoincr"`
Name string `xorm:"varchar(128) 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;
type LoginType int8
const (
PublicKey = 1
PublicKey = 1
UserPassword = 2
)
// 新增
func(host *Host) Create() (insertId int16, err error) {
_, err = Db.Insert(host)
func (host *Host) Create() (insertId int16, err error) {
_, err = Db.Insert(host)
if err == nil {
insertId = host.Id
}
@ -33,16 +32,16 @@ func(host *Host) Create() (insertId int16, err error) {
}
// 更新
func(host *Host) Update(id int, data CommonMap) (int64, error) {
func (host *Host) Update(id int, data CommonMap) (int64, error) {
return Db.Table(host).ID(id).Update(data)
}
// 删除
func(host *Host) Delete(id int) (int64, error) {
func (host *Host) Delete(id int) (int64, error) {
return Db.Id(id).Delete(host)
}
func(host *Host) List() ([]Host, error) {
func (host *Host) List() ([]Host, error) {
host.parsePageAndPageSize()
list := make([]Host, 0)
err := Db.Desc("id").Limit(host.PageSize, host.pageLimitOffset()).Find(&list)
@ -50,19 +49,19 @@ func(host *Host) List() ([]Host, error) {
return list, err
}
func(host *Host) Total() (int64, error) {
func (host *Host) Total() (int64, error) {
return Db.Count(host)
}
func(host *Host) parsePageAndPageSize() {
if (host.Page <= 0) {
func (host *Host) parsePageAndPageSize() {
if host.Page <= 0 {
host.Page = Page
}
if (host.PageSize >= 0 || host.PageSize > MaxPageSize) {
if host.PageSize >= 0 || host.PageSize > MaxPageSize {
host.PageSize = PageSize
}
}
func(host *Host) pageLimitOffset() int {
func (host *Host) pageLimitOffset() int {
return (host.Page - 1) * host.PageSize
}
}

View File

@ -4,16 +4,16 @@ import "errors"
// 创建数据库表
type Migration struct {}
type Migration struct{}
func(migration *Migration) Exec(dbName string) error {
func (migration *Migration) Exec(dbName string) error {
if !isDatabaseExist(dbName) {
return errors.New("数据库不存在")
}
tables := []interface{}{
&User{}, &Task{}, &TaskLog{},&Host{},
&User{}, &Task{}, &TaskLog{}, &Host{},
}
for _, table := range(tables) {
for _, table := range tables {
err := Db.Sync2(table)
if err != nil {
return err
@ -24,8 +24,8 @@ func(migration *Migration) Exec(dbName string) error {
}
// 创建数据库
func isDatabaseExist(name string) bool {
func isDatabaseExist(name string) bool {
_, err := Db.Exec("use ?", name)
return err != nil
}
}

View File

@ -1,11 +1,11 @@
package models
import (
"github.com/go-xorm/xorm"
"fmt"
"github.com/ouqiang/cron-scheduler/modules/setting"
"github.com/go-xorm/core"
_ "github.com/go-sql-driver/mysql"
"github.com/go-xorm/core"
"github.com/go-xorm/xorm"
"github.com/ouqiang/cron-scheduler/modules/setting"
"gopkg.in/macaron.v1"
"strings"
)
@ -16,21 +16,21 @@ type CommonMap map[string]interface{}
var Db *xorm.Engine
const (
Disabled Status = 0 // 禁用
Failure Status = 0 // 失败
Enabled Status = 1 // 启用
Running Status = 1 // 运行中
Finish Status = 2 // 完成
Disabled Status = 0 // 禁用
Failure Status = 0 // 失败
Enabled Status = 1 // 启用
Running Status = 1 // 运行中
Finish Status = 2 // 完成
)
const (
Page = 1 // 当前页数
PageSize = 20 // 每页多少条数据
MaxPageSize = 100000 // 每次最多取多少条
Page = 1 // 当前页数
PageSize = 20 // 每页多少条数据
MaxPageSize = 100000 // 每次最多取多少条
)
// 创建Db
func CreateDb(configFile string) *xorm.Engine{
func CreateDb(configFile string) *xorm.Engine {
config := getDbConfig(configFile)
dsn := getDbEngineDSN(config["engine"], config)
engine, err := xorm.NewEngine(config["engine"], dsn)
@ -56,22 +56,22 @@ func getDbEngineDSN(engine string, config map[string]string) string {
engine = strings.ToLower(engine)
var dsn string = ""
switch engine {
case "mysql":
dsn = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s",
config["user"],
config["password"],
config["host"],
config["port"],
config["database"],
config["charset"])
case "mysql":
dsn = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s",
config["user"],
config["password"],
config["host"],
config["port"],
config["database"],
config["charset"])
}
return dsn
}
// 获取数据库配置
func getDbConfig(configFile string) (map[string]string){
config,err := setting.Read(configFile)
func getDbConfig(configFile string) map[string]string {
config, err := setting.Read(configFile)
if err != nil {
panic(err)
}
@ -90,4 +90,4 @@ func getDbConfig(configFile string) (map[string]string){
db["engine"] = section.Key("engine").String()
return db
}
}

View File

@ -9,9 +9,9 @@ type Protocol int8
type TaskType int8
const (
HTTP Protocol = 1
SSHCommand Protocol = 2
SSHScript Protocol = 3
HTTP Protocol = 1
SSHCommand Protocol = 2
SSHScript Protocol = 3
)
const (
@ -21,28 +21,28 @@ const (
// 任务
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-command 3:ssh-script
Type TaskType `xorm:"tinyint notnull default 1"` // 任务类型 1: 定时任务 2: 延时任务
Command string `xorm:"varchar(512) notnull"` // URL地址或shell命令
Timeout int `xorm:"mediumint notnull default 0"` // 任务执行超时时间(单位秒),0不限制
Delay int `xorm:"int notnull default 0"` // 延时任务,延时时间(单位秒)
SshHosts string `xorm:"varchar(512) notnull defalut '' "` // SSH主机名, host id逗号分隔
Remark string `xorm:"varchar(512) notnull default ''"` // 备注
Created time.Time `xorm:"datetime notnull created"` // 创建时间
Deleted time.Time `xorm:"datetime deleted"` // 删除时间
Status Status `xorm:"tinyint notnull default 1"` // 状态 1:正常 0:停止
Page int `xorm:"-"`
PageSize int `xorm:"-"`
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-command 3:ssh-script
Type TaskType `xorm:"tinyint notnull default 1"` // 任务类型 1: 定时任务 2: 延时任务
Command string `xorm:"varchar(512) notnull"` // URL地址或shell命令
Timeout int `xorm:"mediumint notnull default 0"` // 任务执行超时时间(单位秒),0不限制
Delay int `xorm:"int notnull default 0"` // 延时任务,延时时间(单位秒)
SshHosts string `xorm:"varchar(512) notnull defalut '' "` // SSH主机名, host id逗号分隔
Remark string `xorm:"varchar(512) notnull default ''"` // 备注
Created time.Time `xorm:"datetime notnull created"` // 创建时间
Deleted time.Time `xorm:"datetime deleted"` // 删除时间
Status Status `xorm:"tinyint notnull default 1"` // 状态 1:正常 0:停止
Page int `xorm:"-"`
PageSize int `xorm:"-"`
}
// 新增
func(task *Task) Create() (insertId int, err error) {
func (task *Task) Create() (insertId int, err error) {
task.Status = Enabled
_, err = Db.Insert(task)
_, err = Db.Insert(task)
if err == nil {
insertId = task.Id
}
@ -51,26 +51,26 @@ func(task *Task) Create() (insertId int, err error) {
}
// 更新
func(task *Task) Update(id int, data CommonMap) (int64, error) {
func (task *Task) Update(id int, data CommonMap) (int64, error) {
return Db.Table(task).ID(id).Update(data)
}
// 删除
func(task *Task) Delete(id int) (int64, error) {
func (task *Task) Delete(id int) (int64, error) {
return Db.Id(id).Delete(task)
}
// 禁用
func(task *Task) Disable(id int) (int64, error) {
func (task *Task) Disable(id int) (int64, error) {
return task.Update(id, CommonMap{"status": Disabled})
}
// 激活
func(task *Task) Enable(id int) (int64, error) {
func (task *Task) Enable(id int) (int64, error) {
return task.Update(id, CommonMap{"status": Enabled})
}
func(task *Task) ActiveList() ([]Task, error) {
func (task *Task) ActiveList() ([]Task, error) {
task.parsePageAndPageSize()
list := make([]Task, 0)
err := Db.Where("status = ?", Enabled).Desc("id").Find(&list)
@ -78,7 +78,7 @@ func(task *Task) ActiveList() ([]Task, error) {
return list, err
}
func(task *Task) List() ([]Task, error) {
func (task *Task) List() ([]Task, error) {
task.parsePageAndPageSize()
list := make([]Task, 0)
err := Db.Desc("id").Limit(task.PageSize, task.pageLimitOffset()).Find(&list)
@ -86,19 +86,19 @@ func(task *Task) List() ([]Task, error) {
return list, err
}
func(taskLog *TaskLog) Total() (int64, error) {
func (taskLog *TaskLog) Total() (int64, error) {
return Db.Count(taskLog)
}
func(taskLog *TaskLog) parsePageAndPageSize() {
if (taskLog.Page <= 0) {
func (taskLog *TaskLog) parsePageAndPageSize() {
if taskLog.Page <= 0 {
taskLog.Page = Page
}
if (taskLog.PageSize >= 0 || taskLog.PageSize > MaxPageSize) {
if taskLog.PageSize >= 0 || taskLog.PageSize > MaxPageSize {
taskLog.PageSize = PageSize
}
}
func(taskLog *TaskLog) pageLimitOffset() int {
func (taskLog *TaskLog) pageLimitOffset() int {
return (taskLog.Page - 1) * taskLog.PageSize
}
}

View File

@ -5,21 +5,21 @@ import (
)
// 任务执行日志
type TaskLog struct{
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 '' "` // 执行结果
Page int `xorm:"-"`
PageSize int `xorm:"-"`
type TaskLog struct {
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 '' "` // 执行结果
Page int `xorm:"-"`
PageSize int `xorm:"-"`
}
func(taskLog *TaskLog) Create() (insertId int, err error) {
func (taskLog *TaskLog) Create() (insertId int, err error) {
taskLog.Status = Running
_, err = Db.Insert(taskLog)
_, err = Db.Insert(taskLog)
if err == nil {
insertId = taskLog.Id
}
@ -28,15 +28,15 @@ func(taskLog *TaskLog) Create() (insertId int, err error) {
}
// 更新
func(taskLog *TaskLog) Update(id int, data CommonMap) (int64, error) {
func (taskLog *TaskLog) Update(id int, data CommonMap) (int64, error) {
return Db.Table(taskLog).ID(id).Update(data)
}
func(taskLog *TaskLog) setStatus(id int ,status Status) (int64, error) {
func (taskLog *TaskLog) setStatus(id int, status Status) (int64, error) {
return taskLog.Update(id, CommonMap{"status": status})
}
func(taskLog *TaskLog) List() ([]TaskLog, error) {
func (taskLog *TaskLog) List() ([]TaskLog, error) {
taskLog.parsePageAndPageSize()
list := make([]TaskLog, 0)
err := Db.Desc("id").Limit(taskLog.PageSize, taskLog.pageLimitOffset()).Find(&list)
@ -44,19 +44,19 @@ func(taskLog *TaskLog) List() ([]TaskLog, error) {
return list, err
}
func(task *Task) Total() (int64, error) {
func (task *Task) Total() (int64, error) {
return Db.Count(task)
}
func(task *Task) parsePageAndPageSize() {
if (task.Page <= 0) {
func (task *Task) parsePageAndPageSize() {
if task.Page <= 0 {
task.Page = Page
}
if (task.PageSize >= 0 || task.PageSize > MaxPageSize) {
if task.PageSize >= 0 || task.PageSize > MaxPageSize {
task.PageSize = PageSize
}
}
func(task *Task) pageLimitOffset() int {
func (task *Task) pageLimitOffset() int {
return (task.Page - 1) * task.PageSize
}
}

View File

@ -1,35 +1,35 @@
package models
import (
"time"
"github.com/ouqiang/cron-scheduler/modules/utils"
"time"
)
const PasswordSaltLength = 6;
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 '' "` // 邮箱
Created time.Time `xorm:"datetime notnull created"`
Updated time.Time `xorm:"datetime updated"`
Deleted time.Time `xorm:"datetime deleted"`
IsAdmin int8 `xorm:"tinyint notnull default 0"` // 是否是管理员 1:管理员 0:普通用户
Status Status `xorm:"tinyint notnull default 1"` // 1: 正常 0:禁用
Page int `xorm:"-"`
PageSize int `xorm:"-"`
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 '' "` // 邮箱
Created time.Time `xorm:"datetime notnull created"`
Updated time.Time `xorm:"datetime updated"`
Deleted time.Time `xorm:"datetime deleted"`
IsAdmin int8 `xorm:"tinyint notnull default 0"` // 是否是管理员 1:管理员 0:普通用户
Status Status `xorm:"tinyint notnull default 1"` // 1: 正常 0:禁用
Page int `xorm:"-"`
PageSize int `xorm:"-"`
}
// 新增
func(user *User) Create() (insertId int, err error) {
user.Status = Enabled
user.Salt = user.generateSalt()
func (user *User) Create() (insertId int, err error) {
user.Status = Enabled
user.Salt = user.generateSalt()
user.Password = user.encryptPassword(user.Password, user.Salt)
_, err = Db.Insert(user)
_, err = Db.Insert(user)
if err == nil {
insertId = user.Id
}
@ -38,34 +38,34 @@ func(user *User) Create() (insertId int, err error) {
}
// 更新
func(user *User) Update(id int, data CommonMap) (int64, error) {
func (user *User) Update(id int, data CommonMap) (int64, error) {
return Db.Table(user).ID(id).Update(data)
}
// 删除
func(user *User) Delete(id int) (int64, error) {
func (user *User) Delete(id int) (int64, error) {
return Db.Id(id).Delete(user)
}
// 禁用
func(user *User) Disable(id int) (int64, error) {
func (user *User) Disable(id int) (int64, error) {
return user.Update(id, CommonMap{"status": Disabled})
}
// 激活
func(user *User) Enable(id int) (int64, error) {
func (user *User) Enable(id int) (int64, error) {
return user.Update(id, CommonMap{"status": Enabled})
}
// 验证用户名和密码
func(user *User) Match(username, password string) bool {
func (user *User) Match(username, password string) bool {
where := "(name = ? OR email = ?)"
_, err := Db.Where(where, username, username).Get(user)
if err != nil {
return false
}
hashPassword := user.encryptPassword(password, user.Salt)
if (hashPassword != user.Password) {
if hashPassword != user.Password {
return false
}
@ -73,17 +73,16 @@ func(user *User) Match(username, password string) bool {
}
// 用户名是否存在
func(user *User) UsernameExists(username string ) (int64, error) {
return Db.Where("name = ?", username).Count(user)
func (user *User) UsernameExists(username string) (int64, error) {
return Db.Where("name = ?", username).Count(user)
}
// 邮箱地址是否存在
func(user *User) EmailExists(email string) (int64, error) {
func (user *User) EmailExists(email string) (int64, error) {
return Db.Where("email = ?", email).Count(user)
}
func(user *User) List() ([]User, error) {
func (user *User) List() ([]User, error) {
user.parsePageAndPageSize()
list := make([]User, 0)
err := Db.Desc("id").Limit(user.PageSize, user.pageLimitOffset()).Find(&list)
@ -91,29 +90,29 @@ func(user *User) List() ([]User, error) {
return list, err
}
func(user *User) Total() (int64, error) {
func (user *User) Total() (int64, error) {
return Db.Count(user)
}
func(user *User) parsePageAndPageSize() {
if (user.Page <= 0) {
func (user *User) parsePageAndPageSize() {
if user.Page <= 0 {
user.Page = Page
}
if (user.PageSize >= 0 || user.PageSize > MaxPageSize) {
if user.PageSize >= 0 || user.PageSize > MaxPageSize {
user.PageSize = PageSize
}
}
func(user *User) pageLimitOffset() int {
func (user *User) pageLimitOffset() int {
return (user.Page - 1) * user.PageSize
}
// 密码加密
func(user *User) encryptPassword(password, salt string) string {
func (user *User) encryptPassword(password, salt string) string {
return utils.Md5(password + salt)
}
// 生成密码盐值
func(user *User) generateSalt() string {
func (user *User) generateSalt() string {
return utils.RandString(PasswordSaltLength)
}
}

View File

@ -7,23 +7,21 @@ import (
"github.com/ouqiang/cron-scheduler/modules/utils"
)
/**
* ad-hoc
* hosts
* hostFile
* module
* args module
*/
func ExecCommand(hosts string, hostFile string, module string, args... string) (output string, err error) {
if hosts== "" || hostFile == "" || module == "" {
*/
func ExecCommand(hosts string, hostFile string, module string, args ...string) (output string, err error) {
if hosts == "" || hostFile == "" || module == "" {
err = errors.New("参数不完整")
return
}
commandArgs := []string{hosts, "-i", hostFile, "-m", module}
commandArgs := []string{hosts, "-i", hostFile, "-m", module}
if len(args) > 0 {
commandArgs = append(commandArgs, args...)
commandArgs = append(commandArgs, args...)
}
output, err = utils.ExecShell("ansible", commandArgs...)
@ -31,16 +29,16 @@ func ExecCommand(hosts string, hostFile string, module string, args... string) (
}
// 执行shell命令
func Shell(hosts string, hostFile string, args... string) (output string, err error) {
func Shell(hosts string, hostFile string, args ...string) (output string, err error) {
return ExecCommand(hosts, hostFile, "shell", args...)
}
// 复制本地脚本到远程执行
func Script(hosts string, hostFile string, args... string) (output string, err error) {
func Script(hosts string, hostFile string, args ...string) (output string, err error) {
return ExecCommand(hosts, hostFile, "script", args...)
}
// 测试主机是否可通
func Ping(hosts string, hostFile string) (output string, err error) {
func Ping(hosts string, hostFile string) (output string, err error) {
return ExecCommand(hosts, hostFile, "ping")
}
}

View File

@ -1,12 +1,12 @@
package ansible
import (
"github.com/ouqiang/cron-scheduler/models"
"sync"
"io/ioutil"
"bytes"
"strconv"
"github.com/ouqiang/cron-scheduler/models"
"github.com/ouqiang/cron-scheduler/modules/utils"
"io/ioutil"
"strconv"
"sync"
)
// 主机名
@ -17,7 +17,7 @@ type Hosts struct {
filename string
}
func NewHosts(hostFilename string) *Hosts {
func NewHosts(hostFilename string) *Hosts {
h := &Hosts{sync.RWMutex{}, hostFilename}
h.Write()
@ -25,16 +25,15 @@ func NewHosts(hostFilename string) *Hosts {
}
// 获取hosts文件名
func(h *Hosts) GetFilename() string {
func (h *Hosts) GetFilename() string {
h.RLock()
defer h.RUnlock()
return h.filename
}
// 写入hosts
func(h *Hosts) Write() {
func (h *Hosts) Write() {
host := new(models.Host)
hostModels, err := host.List()
if err != nil {
@ -46,7 +45,7 @@ func(h *Hosts) Write() {
return
}
buffer := bytes.Buffer{}
for _, hostModel := range(hostModels) {
for _, hostModel := range hostModels {
buffer.WriteString(strconv.Itoa(int(hostModel.Id)))
buffer.WriteString(" ansible_ssh_host=")
buffer.WriteString(hostModel.Name)
@ -54,7 +53,7 @@ func(h *Hosts) Write() {
buffer.WriteString(strconv.Itoa(hostModel.Port))
buffer.WriteString(" ansible_ssh_user=")
buffer.WriteString(hostModel.Username)
if (hostModel.LoginType != models.PublicKey && hostModel.Password != "") {
if hostModel.LoginType != models.PublicKey && hostModel.Password != "" {
buffer.WriteString(" ansible_ssh_pass=")
buffer.WriteString(hostModel.Password)
}
@ -66,5 +65,3 @@ func(h *Hosts) Write() {
return
}

View File

@ -4,21 +4,21 @@ import (
"os"
"runtime"
"github.com/ouqiang/cron-scheduler/modules/utils"
"github.com/ouqiang/cron-scheduler/modules/crontask"
"github.com/ouqiang/cron-scheduler/models"
"github.com/ouqiang/cron-scheduler/modules/ansible"
"github.com/ouqiang/cron-scheduler/modules/crontask"
"github.com/ouqiang/cron-scheduler/modules/utils"
"github.com/ouqiang/cron-scheduler/service"
)
var (
AppDir string // 应用根目录
ConfDir string // 配置目录
LogDir string // 日志目录
DataDir string // 数据目录存放session文件等
AppConfig string // 应用配置文件
var (
AppDir string // 应用根目录
ConfDir string // 配置目录
LogDir string // 日志目录
DataDir string // 数据目录存放session文件等
AppConfig string // 应用配置文件
AnsibleHosts string // ansible hosts文件
Installed bool // 应用是否安装过
Installed bool // 应用是否安装过
)
func InitEnv() {
@ -29,7 +29,7 @@ func InitEnv() {
}
AppDir = wd
ConfDir = AppDir + "/conf"
LogDir = AppDir + "/log"
LogDir = AppDir + "/log"
DataDir = AppDir + "/data"
AppConfig = ConfDir + "/app.ini"
AnsibleHosts = ConfDir + "/ansible_hosts.ini"
@ -54,7 +54,7 @@ func IsInstalled() bool {
}
// 检测环境
func CheckEnv() {
func CheckEnv() {
// ansible不支持安装在windows上, windows只能作为被控机
if runtime.GOOS == "windows" {
panic("不支持在windows上运行")
@ -79,7 +79,6 @@ func CreateInstallLock() error {
return err
}
// 初始化资源
func InitResource() {
// 初始化ansible Hosts
@ -91,13 +90,13 @@ func InitResource() {
}
// 初始化DB
func InitDb() {
func InitDb() {
models.Db = models.CreateDb(AppConfig)
}
// 检测目录是否存在
func checkDirExists(path... string) {
for _, value := range(path) {
func checkDirExists(path ...string) {
for _, value := range path {
_, err := os.Stat(value)
if os.IsNotExist(err) {
panic(value + "目录不存在")
@ -106,4 +105,4 @@ func checkDirExists(path... string) {
panic(value + "目录无权限操作")
}
}
}
}

View File

@ -1,10 +1,10 @@
package crontask
import (
"github.com/robfig/cron"
"errors"
"sync"
"github.com/robfig/cron"
"strings"
"sync"
)
var DefaultCronTask *CronTask
@ -17,7 +17,7 @@ type CronTask struct {
}
func NewCronTask() *CronTask {
return &CronTask {
return &CronTask{
sync.RWMutex{},
make(CronMap),
}
@ -26,7 +26,7 @@ func NewCronTask() *CronTask {
// 新增定时任务,如果name存在则添加失败
// name 任务名称
// spec crontab时间格式定义 可定义多个时间\n分隔
func(cronTask *CronTask) Add(name string, spec string, cmd cron.FuncJob ) (err error) {
func (cronTask *CronTask) Add(name string, spec string, cmd cron.FuncJob) (err error) {
if name == "" || spec == "" || cmd == nil {
return errors.New("参数不完整")
}
@ -39,13 +39,13 @@ func(cronTask *CronTask) Add(name string, spec string, cmd cron.FuncJob ) (err e
defer cronTask.Unlock()
cronTask.tasks[name] = cron.New()
specs := strings.Split(spec, "|||")
for _, item := range(specs) {
for _, item := range specs {
_, err = cron.Parse(item)
if err != nil {
return err
}
}
for _, item := range(specs) {
for _, item := range specs {
err = cronTask.tasks[name].AddFunc(item, cmd)
}
cronTask.tasks[name].Start()
@ -54,7 +54,7 @@ func(cronTask *CronTask) Add(name string, spec string, cmd cron.FuncJob ) (err e
}
// 任务不存在则新增,任务已存在则删除后新增
func(cronTask *CronTask) AddOrReplace(name string, spec string, cmd cron.FuncJob) error {
func (cronTask *CronTask) AddOrReplace(name string, spec string, cmd cron.FuncJob) error {
if cronTask.IsExist(name) {
cronTask.Delete(name)
}
@ -62,9 +62,8 @@ func(cronTask *CronTask) AddOrReplace(name string, spec string, cmd cron.FuncJob
return cronTask.Add(name, spec, cmd)
}
// 判断任务是否存在
func(cronTask *CronTask) IsExist(name string) bool {
func (cronTask *CronTask) IsExist(name string) bool {
cronTask.RLock()
defer cronTask.RUnlock()
_, ok := cronTask.tasks[name]
@ -73,16 +72,16 @@ func(cronTask *CronTask) IsExist(name string) bool {
}
// 停止任务
func(cronTask *CronTask) Stop(name string) {
func (cronTask *CronTask) Stop(name string) {
if cronTask.IsExist(name) {
cronTask.tasks[name].Stop()
}
}
// 删除任务
func(cronTask *CronTask) Delete(name string) {
func (cronTask *CronTask) Delete(name string) {
cronTask.Stop(name)
cronTask.Lock()
defer cronTask.Unlock()
delete(cronTask.tasks, name)
}
}

View File

@ -1,8 +1,8 @@
package setting
import (
"gopkg.in/ini.v1"
"errors"
"gopkg.in/ini.v1"
)
// 读取配置
@ -15,15 +15,14 @@ func Read(filename string) (config *ini.File, err error) {
return
}
// 写入配置
func Write(config map[string]map[string]string, filename string) (error) {
func Write(config map[string]map[string]string, filename string) error {
if len(config) == 0 {
return errors.New("参数不能为空")
}
file := ini.Empty()
for sectionName, items := range(config) {
for sectionName, items := range config {
if sectionName == "" {
return errors.New("节名称不能为空")
}
@ -31,7 +30,7 @@ func Write(config map[string]map[string]string, filename string) (error) {
if err != nil {
return err
}
for key, value := range(items) {
for key, value := range items {
_, err = section.NewKey(key, value)
if err != nil {
return err
@ -41,4 +40,4 @@ func Write(config map[string]map[string]string, filename string) (error) {
err := file.SaveTo(filename)
return err
}
}

View File

@ -5,29 +5,29 @@ import "encoding/json"
// json 格式输出
type response struct {
Code int `json:"code"` // 状态码 0:成功 非0:失败
Message string `json:"message"` // 信息
Data interface{} `json:"data"` // 数据
Code int `json:"code"` // 状态码 0:成功 非0:失败
Message string `json:"message"` // 信息
Data interface{} `json:"data"` // 数据
}
type Json struct {}
type Json struct{}
const ResponseSuccess = 0;
const ResponseFailure = 1;
const ResponseSuccess = 0
const ResponseFailure = 1
func(j *Json) Success(message string, data interface{}) string {
func (j *Json) Success(message string, data interface{}) string {
return j.response(ResponseSuccess, message, data)
}
func(j *Json) Failure(code int, message string) string {
func (j *Json) Failure(code int, message string) string {
return j.response(code, message, nil)
}
func(j *Json) response(code int, message string, data interface{}) (string) {
func (j *Json) response(code int, message string, data interface{}) string {
resp := response{
Code: code,
Code: code,
Message: message,
Data: data,
Data: data,
}
result, err := json.Marshal(resp)
@ -37,4 +37,3 @@ func(j *Json) response(code int, message string, data interface{}) (string) {
return string(result)
}

View File

@ -1,17 +1,16 @@
package utils
import (
"os/exec"
"math/rand"
"time"
"crypto/md5"
"encoding/hex"
"log"
"math/rand"
"os/exec"
"time"
)
// 执行shell命令
func ExecShell(command string, args... string) (string, error) {
func ExecShell(command string, args ...string) (string, error) {
result, err := exec.Command(command, args...).CombinedOutput()
return string(result), err
@ -48,6 +47,6 @@ func RandNumber(max int) int {
// 日志记录
// todo 保存到哪里 文件,数据库还是elasticsearch?,暂时输出到终端
func RecordLog(v... interface{}) {
func RecordLog(v ...interface{}) {
log.Println(v)
}
}

View File

@ -28,4 +28,4 @@ func TestRandNumber(t *testing.T) {
if num <= 0 && num >= 10000 {
t.Fatalf("随机数不在有效范围内-%d", num)
}
}
}

View File

@ -1,31 +1,31 @@
package install
import (
"gopkg.in/macaron.v1"
"github.com/ouqiang/cron-scheduler/modules/app"
"github.com/ouqiang/cron-scheduler/modules/utils"
"github.com/ouqiang/cron-scheduler/models"
"github.com/ouqiang/cron-scheduler/modules/app"
"github.com/ouqiang/cron-scheduler/modules/setting"
"github.com/ouqiang/cron-scheduler/modules/utils"
"gopkg.in/macaron.v1"
"strconv"
)
// 系统安装
type InstallForm struct {
DbType string `binding:"IN(mysql)"`
DbHost string `binding:"Required"`
DbPort int `binding:"Required"`
DbUsername string `binding:"Required"`
DbPassword string `binding:"Required"`
DbName string `binding:"Required"`
DbType string `binding:"IN(mysql)"`
DbHost string `binding:"Required"`
DbPort int `binding:"Required"`
DbUsername string `binding:"Required"`
DbPassword string `binding:"Required"`
DbName string `binding:"Required"`
DbTablePrefix string
AdminUsername string `binding:"Required;MinSize(3)"`
AdminPassword string `binding:"Required;MinSize(6)"`
AdminEmail string `binding:"Email"`
AdminEmail string `binding:"Email"`
}
// 显示安装页面
func Show(ctx *macaron.Context) {
func Show(ctx *macaron.Context) {
if app.Installed {
ctx.Redirect("/")
}
@ -81,14 +81,14 @@ func Install(ctx *macaron.Context, form InstallForm) string {
func writeConfig(form InstallForm) error {
dbConfig := map[string]map[string]string{
"db": map[string]string{
"engine": form.DbType,
"host": form.DbHost,
"port": strconv.Itoa(form.DbPort),
"user": form.DbUsername,
"engine": form.DbType,
"host": form.DbHost,
"port": strconv.Itoa(form.DbPort),
"user": form.DbUsername,
"password": form.DbPassword,
"database": form.DbName,
"prefix": form.DbTablePrefix,
"charset": "utf8",
"prefix": form.DbTablePrefix,
"charset": "utf8",
},
}
@ -105,4 +105,4 @@ func createAdminUser(form InstallForm) error {
_, err := user.Create()
return err
}
}

View File

@ -1,9 +1,9 @@
package routers
import (
"gopkg.in/macaron.v1"
"github.com/ouqiang/cron-scheduler/routers/install"
"github.com/go-macaron/binding"
"github.com/ouqiang/cron-scheduler/routers/install"
"gopkg.in/macaron.v1"
)
// 路由注册
@ -19,7 +19,7 @@ func Register(m *macaron.Macaron) {
ctx.HTML(500, "error/500")
})
// 首页
m.Get("/", func(ctx *macaron.Context) (string) {
m.Get("/", func(ctx *macaron.Context) string {
return "go home"
})
// 系统安装
@ -27,4 +27,4 @@ func Register(m *macaron.Macaron) {
m.Get("", install.Show)
m.Post("", binding.Bind(install.InstallForm{}), install.Install)
})
}
}

View File

@ -1,22 +1,22 @@
package service
import (
"fmt"
"github.com/ouqiang/cron-scheduler/models"
"github.com/ouqiang/cron-scheduler/modules/ansible"
"github.com/ouqiang/cron-scheduler/modules/crontask"
"github.com/ouqiang/cron-scheduler/modules/utils"
"net/http"
"github.com/robfig/cron"
"io/ioutil"
"net/http"
"strconv"
"time"
"github.com/ouqiang/cron-scheduler/modules/crontask"
"github.com/robfig/cron"
"github.com/ouqiang/cron-scheduler/modules/ansible"
"fmt"
)
type Task struct {}
type Task struct{}
// 初始化任务, 从数据库取出所有任务, 添加到定时任务并运行
func(task *Task) Initialize() {
func (task *Task) Initialize() {
taskModel := new(models.Task)
taskList, err := taskModel.ActiveList()
if err != nil {
@ -27,15 +27,13 @@ func(task *Task) Initialize() {
utils.RecordLog("任务列表为空")
return
}
for _, item := range(taskList) {
for _, item := range taskList {
task.Add(item)
}
}
// 添加任务
func(task *Task) Add(taskModel models.Task) {
func (task *Task) Add(taskModel models.Task) {
taskFunc := createHandlerJob(taskModel)
if taskFunc == nil {
utils.RecordLog("添加任务#不存在的任务协议编号", taskModel.Protocol)
@ -49,7 +47,7 @@ func(task *Task) Add(taskModel models.Task) {
}
} else if taskModel.Type == models.Delay {
// 延时任务
time.AfterFunc(time.Duration(taskModel.Delay) * time.Second, taskFunc)
time.AfterFunc(time.Duration(taskModel.Delay)*time.Second, taskFunc)
}
}
@ -58,11 +56,11 @@ type Handler interface {
}
// HTTP任务
type HTTPHandler struct {}
type HTTPHandler struct{}
func(h *HTTPHandler) Run(taskModel models.Task) (result string, err error) {
func (h *HTTPHandler) Run(taskModel models.Task) (result string, err error) {
client := &http.Client{}
if (taskModel.Timeout > 0) {
if taskModel.Timeout > 0 {
client.Timeout = time.Duration(taskModel.Timeout) * time.Second
}
req, err := http.NewRequest("POST", taskModel.Command, nil)
@ -88,36 +86,35 @@ func(h *HTTPHandler) Run(taskModel models.Task) (result string, err error) {
utils.RecordLog("读取HTTP请求返回值失败-", err.Error())
}
return string(body),err
return string(body), err
}
// SSH-command任务
type SSHCommandHandler struct {}
type SSHCommandHandler struct{}
func(ssh *SSHCommandHandler) Run(taskModel models.Task) (string, error) {
func (ssh *SSHCommandHandler) Run(taskModel models.Task) (string, error) {
return execSSHHandler("shell", taskModel)
}
// SSH-script任务
type SSHScriptHandler struct {}
type SSHScriptHandler struct{}
func(ssh *SSHScriptHandler) Run(taskModel models.Task) (string, error) {
func (ssh *SSHScriptHandler) Run(taskModel models.Task) (string, error) {
return execSSHHandler("script", taskModel)
}
// SSH任务
func execSSHHandler(module string, taskModel models.Task) (string, error) {
var args []string = []string{ taskModel.Command }
if (taskModel.Timeout > 0) {
func execSSHHandler(module string, taskModel models.Task) (string, error) {
var args []string = []string{taskModel.Command}
if taskModel.Timeout > 0 {
// -B 异步执行超时时间, -P 轮询时间
args = append(args, "-B", strconv.Itoa(taskModel.Timeout), "-P", "10")
}
if module == "shell" {
return ansible.Shell(taskModel.SshHosts, ansible.DefaultHosts.GetFilename(), args...)
return ansible.Shell(taskModel.SshHosts, ansible.DefaultHosts.GetFilename(), args...)
}
if module == "script" {
return ansible.Script(taskModel.SshHosts, ansible.DefaultHosts.GetFilename(), args...)
return ansible.Script(taskModel.SshHosts, ansible.DefaultHosts.GetFilename(), args...)
}
return "", nil
@ -146,19 +143,19 @@ func updateTaskLog(taskLogId int, result string, err error) (int64, error) {
return taskLogModel.Update(taskLogId, models.CommonMap{
"status": status,
"result": result,
});
})
}
func createHandlerJob(taskModel models.Task) cron.FuncJob {
var handler Handler = nil
switch taskModel.Protocol {
case models.HTTP:
handler = new(HTTPHandler)
case models.SSHCommand:
handler = new(SSHCommandHandler)
case models.SSHScript:
handler = new(SSHScriptHandler)
case models.HTTP:
handler = new(HTTPHandler)
case models.SSHCommand:
handler = new(SSHCommandHandler)
case models.SSHScript:
handler = new(SSHScriptHandler)
}
taskFunc := func() {
taskLogId, err := createTaskLog(taskModel.Id)
@ -175,4 +172,4 @@ func createHandlerJob(taskModel models.Task) cron.FuncJob {
}
return taskFunc
}
}