Пример #1
0
//Shell commands
func (p *Engine) Shell() []cli.Command {
	return []cli.Command{

		{
			Name:    "reading",
			Aliases: []string{"rd"},
			Usage:   "reading engine operations",
			Subcommands: []cli.Command{
				{
					Name:    "scan",
					Usage:   "scan books",
					Aliases: []string{"s"},
					Action: web.IocAction(func(*cli.Context, *inject.Graph) error {
						return p._scanBooks()
					}),
				},
			},
		},
	}
}
Пример #2
0
//Shell shell commands
func (p *Engine) Shell() []cli.Command {
	return []cli.Command{
		{
			Name:    "nginx",
			Aliases: []string{"ng"},
			Usage:   "init nginx config file",
			Action: web.Action(func(*cli.Context) error {
				const tpl = `
upstream {{.Domain}}_prod {
  server localhost:{{.Port}} fail_timeout=0;
}

server {
  listen {{if .Ssl}}443{{- else}}80{{- end}};

{{if .Ssl}}
  ssl  on;
  ssl_certificate  ssl/{{.Domain}}-cert.pem;
  ssl_certificate_key  ssl/{{.Domain}}-key.pem;
  ssl_session_timeout  5m;
  ssl_protocols  SSLv2 SSLv3 TLSv1;
  ssl_ciphers  RC4:HIGH:!aNULL:!MD5;
  ssl_prefer_server_ciphers  on;
{{- end}}

  client_max_body_size 4G;
  keepalive_timeout 10;

  proxy_buffers 16 64k;
  proxy_buffer_size 128k;

  server_name {{.Domain}};

  root {{.Root}}/public;
  index index.html;

  access_log /var/log/nginx/{{.Domain}}.access.log;
  error_log /var/log/nginx/{{.Domain}}.error.log;

  location / {
    try_files $uri $uri/ /index.html?/$request_uri;
  }

#  location ^~ /assets/ {
#    gzip_static on;
#    expires max;
#    access_log off;
#    add_header Cache-Control "public";
#  }

  location ~* \.(?:css|js)$ {
    gzip_static on;
    expires max;
    access_log off;
    add_header Cache-Control "public";
  }
  location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
    expires 1M;
    access_log off;
    add_header Cache-Control "public";
  }

  location ~* \.(?:rss|atom)$ {
    expires 12h;
    access_log off;
    add_header Cache-Control "public";
  }

  location ~ ^/api/{{.Version}}(/?)(.*) {
    {{if .Ssl}}proxy_set_header X-Forwarded-Proto https;{{- end}}
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_redirect off;
    proxy_pass http://{{.Domain}}_prod/$2$is_args$args;
    # limit_req zone=one;
  }

}

`
				t, err := template.New("").Parse(tpl)
				if err != nil {
					return err
				}
				pwd, err := os.Getwd()
				if err != nil {
					return err
				}

				domain := viper.GetString("http.domain")
				fn := path.Join("etc", "nginx", "sites-enabled", domain+".conf")
				if err = os.MkdirAll(path.Dir(fn), 0700); err != nil {
					return err
				}
				fmt.Printf("generate file %s\n", fn)
				fd, err := os.OpenFile(fn, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600)
				if err != nil {
					return err
				}
				defer fd.Close()

				return t.Execute(fd, struct {
					Domain  string
					Port    int
					Ssl     bool
					Root    string
					Version string
				}{
					Ssl:     viper.GetBool("http.ssl"),
					Domain:  domain,
					Port:    viper.GetInt("http.port"),
					Root:    pwd,
					Version: "v1",
				})
			}),
		},
		{
			Name:    "redis",
			Aliases: []string{"re"},
			Usage:   "open redis connection",
			Action: web.Action(func(*cli.Context) error {
				return Shell(
					"redis-cli",
					"-h", viper.GetString("redis.host"),
					"-p", viper.GetString("redis.port"),
					"-n", viper.GetString("redis.db"),
				)
			}),
		},
		{
			Name:    "database",
			Aliases: []string{"db"},
			Usage:   "database operations",
			Subcommands: []cli.Command{
				{
					Name:    "example",
					Usage:   "scripts example for create database and user",
					Aliases: []string{"e"},
					Action: web.Action(func(*cli.Context) error {
						drv := viper.GetString("database.driver")
						args := viper.GetStringMapString("database.args")
						var err error
						switch drv {
						case "postgres":
							fmt.Printf("CREATE USER %s WITH PASSWORD '%s';\n", args["user"], args["password"])
							fmt.Printf("CREATE DATABASE %s WITH ENCODING='UTF8';\n", args["dbname"])
							fmt.Printf("GRANT ALL PRIVILEGES ON DATABASE %s TO %s;\n", args["dbname"], args["user"])
						default:
							err = fmt.Errorf("unknown driver %s", drv)
						}
						return err
					}),
				},
				{
					Name:    "migrate",
					Usage:   "migrate the database",
					Aliases: []string{"m"},
					Action: web.Action(func(*cli.Context) error {
						db, err := web.OpenDatabase()
						if err != nil {
							return err
						}
						return web.Loop(func(en web.Engine) error {
							en.Migrate(db)
							return nil
						})
					}),
				},
				{
					Name:    "seed",
					Usage:   "load the seed data",
					Aliases: []string{"s"},
					Action: web.IocAction(func(*cli.Context, *inject.Graph) error {
						return web.Loop(func(en web.Engine) error {
							en.Seed()
							return nil
						})
					}),
				},
				{
					Name:    "connect",
					Usage:   "connect database",
					Aliases: []string{"c"},
					Action: web.Action(func(*cli.Context) error {
						drv := viper.GetString("database.driver")
						args := viper.GetStringMapString("database.args")
						var err error
						switch drv {
						case "postgres":
							err = Shell("psql",
								"-h", args["host"],
								"-p", args["port"],
								"-U", args["user"],
								args["dbname"],
							)
						default:
							err = fmt.Errorf("unknown driver %s", drv)
						}
						return err
					}),
				},
				{
					Name:    "create",
					Usage:   "create database",
					Aliases: []string{"n"},
					Action: web.Action(func(*cli.Context) error {
						drv := viper.GetString("database.driver")
						args := viper.GetStringMapString("database.args")
						var err error
						switch drv {
						case "postgres":
							err = Shell("psql",
								"-h", args["host"],
								"-p", args["port"],
								"-U", args["user"],
								"-c", fmt.Sprintf("create database %s WITH ENCODING='UTF8'", args["dbname"]),
							)
						default:
							err = fmt.Errorf("unknown driver %s", drv)
						}
						return err
					}),
				},
				{
					Name:    "drop",
					Usage:   "drop database",
					Aliases: []string{"d"},
					Action: web.Action(func(*cli.Context) error {
						drv := viper.GetString("database.driver")
						args := viper.GetStringMapString("database.args")
						var err error
						switch drv {
						case "postgres":
							err = Shell("psql",
								"-h", args["host"],
								"-p", args["port"],
								"-U", args["user"],
								"-c", fmt.Sprintf("drop database %s", args["dbname"]),
							)
						default:
							err = fmt.Errorf("unknown driver %s", drv)
						}
						return err
					}),
				},
			},
		},
		{
			Name:    "cache",
			Aliases: []string{"c"},
			Usage:   "cache operations",
			Subcommands: []cli.Command{
				{
					Name:    "list",
					Usage:   "list all cache keys",
					Aliases: []string{"l"},
					Action: web.IocAction(func(*cli.Context, *inject.Graph) error {
						keys, err := p.Cache.Keys()
						if err != nil {
							return err
						}
						for _, k := range keys {
							fmt.Println(k)
						}
						return nil
					}),
				},
				{
					Name:    "clear",
					Usage:   "clear cache items",
					Aliases: []string{"c"},
					Action: web.IocAction(func(*cli.Context, *inject.Graph) error {
						return p.Cache.Flush()
					}),
				},
			},
		},
		{
			Name:    "oauth",
			Aliases: []string{"oa"},
			Usage:   "oauth credentials.",
			Subcommands: []cli.Command{
				{
					Name:    "google",
					Usage:   "google oauth v2",
					Aliases: []string{"g"},
					Flags: []cli.Flag{
						cli.StringFlag{
							Name:  "file, f",
							Value: "",
							Usage: "google oauth2 json filename.",
						},
					},
					Action: web.IocAction(func(c *cli.Context, g *inject.Graph) error {
						fn := c.String("file")
						if fn == "" {
							return errors.New("filename mustn't empty")
						}

						fd, err := os.Open(fn)
						if err != nil {
							return err
						}
						defer fd.Close()

						var gc GoogleCredential
						dec := json.NewDecoder(fd)
						if err := dec.Decode(&gc); err != nil {
							return err
						}
						return p.Dao.Set("google.oauth", gc.To(), true)
					}),
				},
			},
		},
		{
			Name:    "users",
			Aliases: []string{"us"},
			Usage:   "users manager",
			Subcommands: []cli.Command{
				{
					Name:    "list",
					Usage:   "list all users",
					Aliases: []string{"l"},
					Action: web.IocAction(func(*cli.Context, *inject.Graph) error {
						var us []User
						if err := p.Dao.Db.
							Select([]string{"uid", "name", "email"}).
							Order("last_sign_in DESC").
							Find(&us).Error; err != nil {
							return err
						}
						fmt.Println("UID\tUSER")
						for _, u := range us {
							fmt.Printf("%s\t%s<%s>\n", u.UID, u.Name, u.Email)
						}
						return nil
					}),
				},
				{
					Name:    "role",
					Usage:   "add/remove user's role",
					Aliases: []string{"r"},
					Flags: []cli.Flag{
						cli.StringFlag{
							Name:  "uid, u",
							Value: "",
							Usage: "user's uid",
						},
						cli.StringFlag{
							Name:  "name, n",
							Value: "",
							Usage: "role's name",
						},
						cli.BoolFlag{
							Name:  "deny, d",
							Usage: "remove role from user",
						},
						cli.IntFlag{
							Name:  "years, y",
							Value: 10,
							Usage: "years",
						},
					},
					Action: web.IocAction(func(c *cli.Context, _ *inject.Graph) error {
						uid := c.String("uid")
						name := c.String("name")
						deny := c.Bool("deny")
						years := c.Int("years")
						if uid == "" {
							return errors.New("uid mustn't empty")
						}
						if name == "" {
							return errors.New("role's name mustn't empty")
						}
						user, err := p.Dao.GetUser(uid)
						if err != nil {
							return err
						}
						role, err := p.Dao.Role(name, "-", 0)
						if err != nil {
							return err
						}
						if deny {
							err = p.Dao.Deny(role.ID, user.ID)
						} else {
							err = p.Dao.Allow(role.ID, user.ID, years, 0, 0)
						}
						return err
					}),
				},
			},
		},
	}
}