mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 18:51:03 +01:00
update iriscontrol - no new feature added but now listens to the parent host https://github.com/kataras/iris/issues/191
This commit is contained in:
parent
2942d384c4
commit
2f6c083232
|
@ -9,7 +9,6 @@ Would be readily available to anyone who could intercept the HTTP request.
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/iris-contrib/npm"
|
"github.com/iris-contrib/npm"
|
||||||
"github.com/kataras/iris"
|
"github.com/kataras/iris"
|
||||||
|
@ -91,17 +90,7 @@ func (e *Plugin) PreListen(s *iris.Framework) {
|
||||||
e.certfile = s.Config.Server.CertFile
|
e.certfile = s.Config.Server.CertFile
|
||||||
|
|
||||||
if e.config.Host == "" {
|
if e.config.Host == "" {
|
||||||
h := s.Config.Server.ListeningAddr
|
e.config.Host = s.HTTPServer.VirtualHostname()
|
||||||
|
|
||||||
if idx := strings.Index(h, ":"); idx >= 0 {
|
|
||||||
h = h[0:idx]
|
|
||||||
}
|
|
||||||
if h == "" {
|
|
||||||
h = "127.0.0.1"
|
|
||||||
}
|
|
||||||
|
|
||||||
e.config.Host = h
|
|
||||||
|
|
||||||
}
|
}
|
||||||
e.start()
|
e.start()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
## Iris Control
|
|
||||||
|
|
||||||
### THIS IS NOT READY YET
|
|
||||||
|
|
||||||
This plugin will give you remotely ( and local ) access to your iris server's information via a web interface
|
|
||||||
|
|
||||||
|
|
||||||
### Assets
|
|
||||||
No assets here because this is go -getable folder I don't want to messup with the folder size, in order to solve this
|
|
||||||
I created a downloader manager inside this package which downloads the first time the assets and unzip them to the kataras/iris/plugin/iris-control/iris-control-assets/ .
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The assets files are inside [this repository](https://github.com/iris-contrib/iris-control-assets)
|
|
||||||
|
|
||||||
|
|
||||||
## How to use
|
|
||||||
|
|
||||||
```go
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/kataras/iris"
|
|
||||||
"github.com/kataras/iris/plugin/iriscontrol"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
|
|
||||||
iris.Plugins.Add(iriscontrol.Web(9090, map[string]string{
|
|
||||||
"irisusername1": "irispassword1",
|
|
||||||
"irisusername2": "irispassowrd2",
|
|
||||||
}))
|
|
||||||
|
|
||||||
iris.Get("/", func(ctx *iris.Context) {
|
|
||||||
})
|
|
||||||
|
|
||||||
iris.Post("/something", func(ctx *iris.Context) {
|
|
||||||
})
|
|
||||||
|
|
||||||
iris.Listen(":8080")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
|
@ -1,114 +0,0 @@
|
||||||
package iriscontrol
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/kataras/iris"
|
|
||||||
"github.com/kataras/iris/config"
|
|
||||||
)
|
|
||||||
|
|
||||||
var pathSeperator = string(os.PathSeparator)
|
|
||||||
var pluginPath = os.Getenv("GOPATH") + pathSeperator + "src" + pathSeperator + "github.com" + pathSeperator + "kataras" + pathSeperator + "iris" + pathSeperator + "plugin" + pathSeperator + "iriscontrol" + pathSeperator
|
|
||||||
var assetsURL = "https://github.com/iris-contrib/iris-control-assets/archive/master.zip"
|
|
||||||
var assetsFolderName = "iris-control-assets-master"
|
|
||||||
var installationPath = pluginPath + assetsFolderName + pathSeperator
|
|
||||||
|
|
||||||
// for the plugin server
|
|
||||||
func (i *irisControlPlugin) startControlPanel() {
|
|
||||||
|
|
||||||
// install the assets first
|
|
||||||
if err := i.installAssets(); err != nil {
|
|
||||||
i.pluginContainer.Printf("[%s] %s Error %s: Couldn't install the assets from the internet,\n make sure you are connecting to the internet the first time running the iris-control plugin", time.Now().UTC().String(), Name, err.Error())
|
|
||||||
i.Destroy()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
i.server = iris.New()
|
|
||||||
i.server.Config.DisableBanner = true
|
|
||||||
i.server.Config.Render.Template.Directory = installationPath + "templates"
|
|
||||||
//i.server.SetRenderConfig(i.server.Config.Render)
|
|
||||||
i.setPluginsInfo()
|
|
||||||
i.setPanelRoutes()
|
|
||||||
|
|
||||||
go i.server.Listen(":" + strconv.Itoa(i.options.Port))
|
|
||||||
|
|
||||||
i.pluginContainer.Printf("[%s] %s is running at port %d", time.Now().UTC().String(), Name, i.options.Port)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// DashboardPage is the main data struct for the index
|
|
||||||
// contains a boolean if server is running, the routes and the plugins
|
|
||||||
type DashboardPage struct {
|
|
||||||
ServerIsRunning bool
|
|
||||||
Routes []iris.Route
|
|
||||||
Plugins []PluginInfo
|
|
||||||
LastOperationDateStr string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *irisControlPlugin) setPluginsInfo() {
|
|
||||||
plugins := i.pluginContainer.GetAll()
|
|
||||||
i.plugins = make([]PluginInfo, 0, len(plugins))
|
|
||||||
for _, plugin := range plugins {
|
|
||||||
name := i.pluginContainer.GetName(plugin)
|
|
||||||
desc := i.pluginContainer.GetDescription(plugin)
|
|
||||||
if name == "" {
|
|
||||||
// means an iris internaly plugin or a nameless plugin
|
|
||||||
name = "Internal Iris Plugin"
|
|
||||||
}
|
|
||||||
if desc == "" {
|
|
||||||
// means an iris internaly plugin or a descriptionless plugin
|
|
||||||
desc = "Propably an internal Iris Plugin - no description provided"
|
|
||||||
}
|
|
||||||
|
|
||||||
i.plugins = append(i.plugins, PluginInfo{Name: name, Description: desc})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// installAssets checks if must install ,if yes download the zip and unzip it, returns error.
|
|
||||||
func (i *irisControlPlugin) installAssets() (err error) {
|
|
||||||
//we know already what is the zip folder inside it, so we can check if it's exists, if yes then don't install it again.
|
|
||||||
if i.pluginContainer.GetDownloader().DirectoryExists(installationPath) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
//set the installationPath ,although we know it but do it here too
|
|
||||||
installationPath, err = i.pluginContainer.GetDownloader().Install(assetsURL, pluginPath)
|
|
||||||
return err
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *irisControlPlugin) setPanelRoutes() {
|
|
||||||
|
|
||||||
i.server.Static("/public", installationPath+"static", 1)
|
|
||||||
|
|
||||||
i.server.Use(i.authFunc)
|
|
||||||
i.server.Get("/", func(ctx *iris.Context) {
|
|
||||||
ctx.Render("index.html", DashboardPage{
|
|
||||||
ServerIsRunning: i.station.HTTPServer.IsListening(),
|
|
||||||
Routes: i.routes,
|
|
||||||
Plugins: i.plugins,
|
|
||||||
LastOperationDateStr: i.lastOperationDate.Format(config.TimeFormat),
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
//the controls
|
|
||||||
i.server.Post("/start_server", func(ctx *iris.Context) {
|
|
||||||
//println("server start")
|
|
||||||
i.lastOperationDate = time.Now()
|
|
||||||
old := i.stationServer
|
|
||||||
if !old.IsSecure() {
|
|
||||||
i.station.Listen(old.Config.ListeningAddr)
|
|
||||||
//yes but here it does re- post listen to this plugin so ...
|
|
||||||
} else {
|
|
||||||
i.station.ListenTLS(old.Config.ListeningAddr, old.Config.CertFile, old.Config.KeyFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
i.server.Post("/stop_server", func(ctx *iris.Context) {
|
|
||||||
//println("server stop")
|
|
||||||
i.station.Close()
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
package iriscontrol
|
|
||||||
|
|
||||||
// PluginInfo the name and the description of a plugin
|
|
||||||
type PluginInfo struct {
|
|
||||||
Name string
|
|
||||||
Description string
|
|
||||||
}
|
|
|
@ -1,6 +1,7 @@
|
||||||
package iriscontrol
|
package iriscontrol
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/kataras/iris"
|
"github.com/kataras/iris"
|
||||||
|
@ -8,103 +9,117 @@ import (
|
||||||
"github.com/kataras/iris/middleware/basicauth"
|
"github.com/kataras/iris/middleware/basicauth"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Name the name(string) of this plugin which is Iris Control
|
type (
|
||||||
const Name = "Iris Control"
|
// IrisControl is the interface which the iriscontrol should implements
|
||||||
|
// it's empty for now because no need any public API
|
||||||
|
IrisControl interface{}
|
||||||
|
iriscontrol struct {
|
||||||
|
port int
|
||||||
|
users map[string]string
|
||||||
|
|
||||||
type irisControlPlugin struct {
|
// child is the plugin's standalone station
|
||||||
options config.IrisControl
|
child *iris.Framework
|
||||||
// the pluginContainer is the container which keeps this plugin from the main user's iris instance
|
// the station which this plugins is registed to
|
||||||
pluginContainer iris.PluginContainer
|
parent *iris.Framework
|
||||||
// the station object of the main user's iris instance
|
parentLastOp time.Time
|
||||||
station *iris.Framework
|
|
||||||
//a copy of the server which the main user's iris is listening for
|
|
||||||
stationServer *iris.Server
|
|
||||||
|
|
||||||
// the server is this plugin's server object, it is managed by this plugin only
|
|
||||||
server *iris.Framework
|
|
||||||
//
|
|
||||||
//infos
|
|
||||||
routes []iris.Route
|
|
||||||
plugins []PluginInfo
|
|
||||||
// last time the server was on
|
|
||||||
lastOperationDate time.Time
|
|
||||||
//
|
|
||||||
|
|
||||||
authFunc iris.HandlerFunc
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns the plugin which is ready-to-use inside iris.Plugin method
|
pluginInfo struct {
|
||||||
// receives config.IrisControl
|
Name string
|
||||||
func New(cfg ...config.IrisControl) iris.Plugin {
|
Description string
|
||||||
c := config.DefaultIrisControl()
|
|
||||||
if len(cfg) > 0 {
|
|
||||||
c = cfg[0]
|
|
||||||
}
|
}
|
||||||
if c.Users == nil || len(c.Users) == 0 {
|
)
|
||||||
panic(Name + " Error: you should pass authenticated users map to the options, refer to the docs!")
|
|
||||||
|
var _ IrisControl = &iriscontrol{}
|
||||||
|
|
||||||
|
func (i *iriscontrol) listen(f *iris.Framework) {
|
||||||
|
i.parent = f
|
||||||
|
i.parentLastOp = time.Now()
|
||||||
|
i.initializeChild()
|
||||||
}
|
}
|
||||||
|
|
||||||
auth := basicauth.Default(c.Users)
|
func (i *iriscontrol) initializeChild() {
|
||||||
|
i.child = iris.New()
|
||||||
|
i.child.Config.DisableBanner = true
|
||||||
|
i.child.Config.Render.Template.Directory = assetsPath + "templates"
|
||||||
|
|
||||||
return &irisControlPlugin{options: c, authFunc: auth, routes: make([]iris.Route, 0)}
|
// set the assets
|
||||||
|
i.child.Static("/public", assetsPath+"static", 1)
|
||||||
|
|
||||||
|
// set the authentication middleware
|
||||||
|
i.child.Use(basicauth.New(config.BasicAuth{
|
||||||
|
Users: i.users,
|
||||||
|
ContextKey: "user",
|
||||||
|
Realm: config.DefaultBasicAuthRealm,
|
||||||
|
Expires: time.Duration(1) * time.Hour,
|
||||||
|
}))
|
||||||
|
|
||||||
|
i.child.Get("/", func(ctx *iris.Context) {
|
||||||
|
ctx.MustRender("index.html", iris.Map{
|
||||||
|
"ServerIsRunning": i.parentIsRunning(),
|
||||||
|
"Routes": i.parentLookups(),
|
||||||
|
"Plugins": i.infoPlugins(),
|
||||||
|
"LastOperationDateStr": i.infoLastOp(),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
i.child.Post("/start_server", func(ctx *iris.Context) {
|
||||||
|
|
||||||
|
if !i.parentIsRunning() {
|
||||||
|
// starts the server with its old configuration
|
||||||
|
go func() {
|
||||||
|
if err := i.parent.HTTPServer.Open(); err != nil {
|
||||||
|
i.parent.Logger.Warningf(err.Error())
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
i.parentLastOp = time.Now()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
i.child.Post("/stop_server", func(ctx *iris.Context) {
|
||||||
|
|
||||||
|
if i.parentIsRunning() {
|
||||||
|
i.parentLastOp = time.Now()
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
if err := i.parent.CloseWithErr(); err != nil {
|
||||||
|
i.parent.Logger.Warningf(err.Error())
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
go i.child.Listen(i.parent.HTTPServer.VirtualHostname() + strconv.Itoa(i.port))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Web set the options for the plugin and return the plugin which is ready-to-use inside iris.Plugin method
|
func (i *iriscontrol) parentIsRunning() bool {
|
||||||
// first parameter is port
|
return i.parent != nil && i.parent.HTTPServer.IsListening()
|
||||||
// second parameter is map of users (username:password)
|
|
||||||
func Web(port int, users map[string]string) iris.Plugin {
|
|
||||||
return New(config.IrisControl{Port: port, Users: users})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// implement the base IPlugin
|
func (i *iriscontrol) parentLookups() []iris.Route {
|
||||||
|
if i.parent == nil {
|
||||||
func (i *irisControlPlugin) Activate(container iris.PluginContainer) error {
|
|
||||||
i.pluginContainer = container
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
return i.parent.Lookups()
|
||||||
func (i irisControlPlugin) GetName() string {
|
|
||||||
return Name
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i irisControlPlugin) GetDescription() string {
|
func (i *iriscontrol) infoPlugins() (info []pluginInfo) {
|
||||||
return Name + " is just a web interface which gives you control of your Iris.\n"
|
plugins := i.parent.Plugins
|
||||||
|
for _, p := range plugins.GetAll() {
|
||||||
|
name := plugins.GetName(p)
|
||||||
|
description := plugins.GetDescription(p)
|
||||||
|
if name == "" {
|
||||||
|
name = "Unknown plugin name"
|
||||||
|
}
|
||||||
|
if description == "" {
|
||||||
|
description = "description is not available"
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
info = append(info, pluginInfo{Name: name, Description: description})
|
||||||
|
}
|
||||||
// implement the rest of the plugin
|
return
|
||||||
|
|
||||||
// PostListen sets the station object after the main server starts
|
|
||||||
// starts the actual work of the plugin
|
|
||||||
func (i *irisControlPlugin) PostListen(s *iris.Framework) {
|
|
||||||
//if the first time, because other times start/stop of the server so listen and no listen will be only from the control panel
|
|
||||||
if i.station == nil {
|
|
||||||
i.station = s
|
|
||||||
i.stationServer = i.station.HTTPServer
|
|
||||||
i.lastOperationDate = time.Now()
|
|
||||||
i.routes = s.Lookups()
|
|
||||||
i.startControlPanel()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
func (i *iriscontrol) infoLastOp() string {
|
||||||
|
return i.parentLastOp.Format(config.TimeFormat)
|
||||||
func (i *irisControlPlugin) PreClose(s *iris.Framework) {
|
|
||||||
// Do nothing. This is a wrapper of the main server if we destroy when users stop the main server then we cannot continue the control panel i.Destroy()
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
// Destroy removes entirely the plugin, the options and all of these properties, you cannot re-use this plugin after this method.
|
|
||||||
func (i *irisControlPlugin) Destroy() {
|
|
||||||
i.pluginContainer.Remove(Name)
|
|
||||||
|
|
||||||
i.options = config.IrisControl{}
|
|
||||||
i.routes = nil
|
|
||||||
i.station = nil
|
|
||||||
i.lastOperationDate = config.CookieExpireNever
|
|
||||||
i.server.Close()
|
|
||||||
i.pluginContainer = nil
|
|
||||||
i.authFunc = nil
|
|
||||||
i.pluginContainer.Printf("[%s] %s is turned off", time.Now().UTC().String(), Name)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
package iriscontrol
|
|
||||||
|
|
||||||
// for the main server
|
|
||||||
func (i *irisControlPlugin) StartServer() {
|
|
||||||
if i.station.HTTPServer.IsListening() == false {
|
|
||||||
if i.station.HTTPServer.IsSecure() {
|
|
||||||
//listen with ListenTLS
|
|
||||||
i.station.ListenTLS(i.station.Config.Server.ListeningAddr, i.station.Config.Server.CertFile, i.station.Config.Server.KeyFile)
|
|
||||||
} else {
|
|
||||||
//listen normal
|
|
||||||
i.station.Listen(i.station.Config.Server.ListeningAddr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *irisControlPlugin) StopServer() {
|
|
||||||
if i.station.HTTPServer.IsListening() {
|
|
||||||
i.station.Close()
|
|
||||||
}
|
|
||||||
}
|
|
79
plugin/iriscontrol/plugin.go
Normal file
79
plugin/iriscontrol/plugin.go
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
package iriscontrol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/kataras/iris"
|
||||||
|
"github.com/kataras/iris/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Name "Iris Control"
|
||||||
|
const Name = "Iris Control"
|
||||||
|
|
||||||
|
var (
|
||||||
|
assetsURL = "https://github.com/iris-contrib/iris-control-assets/archive/master.zip"
|
||||||
|
assetsUnzipname = "iris-control-assets"
|
||||||
|
assetsPath = ""
|
||||||
|
)
|
||||||
|
|
||||||
|
// init just sets the assetsPath
|
||||||
|
func init() {
|
||||||
|
homepath := ""
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
homepath = os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
|
||||||
|
} else {
|
||||||
|
homepath = os.Getenv("HOME")
|
||||||
|
}
|
||||||
|
assetsPath = homepath + utils.PathSeparator + ".iris" + utils.PathSeparator + "iris-control-assets" + utils.PathSeparator
|
||||||
|
}
|
||||||
|
|
||||||
|
func installAssets() {
|
||||||
|
|
||||||
|
if !utils.DirectoryExists(assetsPath) {
|
||||||
|
errMsg := "\nProblem while downloading the assets from the internet for the first time. Trace: %s"
|
||||||
|
|
||||||
|
installedDir, err := utils.Install(assetsURL, assetsPath)
|
||||||
|
if err != nil {
|
||||||
|
panic(errMsg)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = utils.CopyDir(installedDir, assetsPath)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to remove the unzipped folder
|
||||||
|
utils.RemoveFile(installedDir[0 : len(installedDir)-1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// New creates & returns a new iris control plugin
|
||||||
|
// receives two parameters
|
||||||
|
// first is the authenticated users which should be able to access the control panel
|
||||||
|
// second is the PORT which the iris control panel should be listened & served to
|
||||||
|
func New(port int, users map[string]string) IrisControl {
|
||||||
|
return &iriscontrol{port: port, users: users}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PreListen registers the iriscontrol plugin
|
||||||
|
func (i *iriscontrol) PreListen(s *iris.Framework) {
|
||||||
|
installAssets()
|
||||||
|
i.listen(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetName returns the name of the plugin
|
||||||
|
func (i *iriscontrol) GetName() string {
|
||||||
|
return Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDescription returns the description of the plugin
|
||||||
|
func (i *iriscontrol) GetDescription() string {
|
||||||
|
return Name + " is just a web interface which gives you control of your Iris.\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
// PreClose any clean-up
|
||||||
|
// temporary is empty because all resources are cleaned graceful by the iris' station
|
||||||
|
func (i *iriscontrol) PreClose(s *iris.Framework) {
|
||||||
|
s.Logger.Infof("Main server terminated")
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user