From d64bcdb51dc5c7b012b7c532a63166ed344de494 Mon Sep 17 00:00:00 2001 From: Brad Rydzewski Date: Thu, 12 Jun 2014 17:17:59 -0700 Subject: [PATCH] Get Config Data via ConfigManager --- Makefile | 2 +- server/conf.go | 86 ------------------------- server/database/config.go | 35 +++++++++++ server/handler/config.go | 8 +-- server/handler/hook.go | 9 ++- server/handler/login.go | 11 ++-- server/handler/repo.go | 7 +-- server/main.go | 93 ++++++++++++++++++++++++--- server/resource/config/manager.go | 34 ---------- server/resource/config/model.go | 94 ---------------------------- server/resource/config/model_test.go | 39 ------------ shared/model/config.go | 93 +++++++++++++++++++++++++++ 12 files changed, 229 insertions(+), 282 deletions(-) delete mode 100644 server/conf.go create mode 100644 server/database/config.go delete mode 100644 server/resource/config/manager.go delete mode 100644 server/resource/config/model.go delete mode 100644 server/resource/config/model_test.go diff --git a/Makefile b/Makefile index 4c8641a63..3fee30371 100644 --- a/Makefile +++ b/Makefile @@ -51,4 +51,4 @@ dpkg: -dpkg-deb --build debian/drone run: - @cd server && go run main.go conf.gomake \ No newline at end of file + @cd server && go run main.go amber.go \ No newline at end of file diff --git a/server/conf.go b/server/conf.go deleted file mode 100644 index 77fabfeae..000000000 --- a/server/conf.go +++ /dev/null @@ -1,86 +0,0 @@ -package main - -import ( - "fmt" - "io/ioutil" - "os" - "os/user" - "path/filepath" - - "github.com/BurntSushi/toml" -) - -// initialize the .drone directory and create a skeleton config -// file if one does not already exist. -func init() { - // load the current user - u, err := user.Current() - if err != nil { - panic(err) - } - - // create the .drone home directory - os.MkdirAll(filepath.Join(u.HomeDir, ".drone"), 0777) - - // check for the config file - filename := filepath.Join(u.HomeDir, ".drone", "config.toml") - if _, err := os.Stat(filename); err != nil { - // if not exists, create - ioutil.WriteFile(filename, []byte(defaultConfig), 0777) - } - - // load the configuration file and parse - if _, err := toml.DecodeFile(filename, &conf); err != nil { - fmt.Println(err) - os.Exit(1) - return - } -} - -var defaultConfig = ` -# Enables user self-registration. If false, the system administrator -# will need to manually add users to the system. -registration = true - -[smtp] -host = "" -port = "" -from = "" -username = "" -password = "" - -[bitbucket] -url = "https://bitbucket.org" -api = "https://bitbucket.org" -client = "" -secret = "" -enabled = false - -[github] -url = "https://github.com" -api = "https://api.github.com" -client = "" -secret = "" -enabled = false - -[githubenterprise] -url = "" -api = "" -client = "" -secret = "" -enabled = false - -[gitlab] -url = "" -api = "" -client = "" -secret = "" -enabled = false - -[stash] -url = "" -api = "" -client = "" -secret = "" -enabled = false -` diff --git a/server/database/config.go b/server/database/config.go new file mode 100644 index 000000000..a04c5d520 --- /dev/null +++ b/server/database/config.go @@ -0,0 +1,35 @@ +package database + +import ( + "github.com/BurntSushi/toml" + "github.com/drone/drone/shared/model" +) + +type ConfigManager interface { + Find() *model.Config +} + +// configManager manages configuration data from a +// configuration file using .toml format +type configManager struct { + conf *model.Config +} + +// NewConfigManager initiales a new CommitManager intended to +// manage and persist commits. +func NewConfigManager(filename string) ConfigManager { + c := configManager{} + c.conf = &model.Config{} + + // load the configuration file and parse + _, err := toml.DecodeFile(filename, c.conf) + if err != nil { + panic(err) + } + + return &c +} + +func (c *configManager) Find() *model.Config { + return c.conf +} diff --git a/server/handler/config.go b/server/handler/config.go index 03bab43fc..7e904bd50 100644 --- a/server/handler/config.go +++ b/server/handler/config.go @@ -4,17 +4,17 @@ import ( "encoding/json" "net/http" - "github.com/drone/drone/server/resource/config" + "github.com/drone/drone/server/database" "github.com/drone/drone/server/session" "github.com/gorilla/pat" ) type ConfigHandler struct { - conf config.Config + conf database.ConfigManager sess session.Session } -func NewConfigHandler(conf config.Config, sess session.Session) *ConfigHandler { +func NewConfigHandler(conf database.ConfigManager, sess session.Session) *ConfigHandler { return &ConfigHandler{conf, sess} } @@ -27,7 +27,7 @@ func (h *ConfigHandler) GetConfig(w http.ResponseWriter, r *http.Request) error return notAuthorized{} } - return json.NewEncoder(w).Encode(h.conf) + return json.NewEncoder(w).Encode(h.conf.Find()) } func (h *ConfigHandler) Register(r *pat.Router) { diff --git a/server/handler/hook.go b/server/handler/hook.go index 8b4f2916a..a73cd2659 100644 --- a/server/handler/hook.go +++ b/server/handler/hook.go @@ -5,7 +5,6 @@ import ( "github.com/drone/drone/server/database" "github.com/drone/drone/server/queue" - "github.com/drone/drone/server/resource/config" "github.com/drone/drone/shared/model" "github.com/gorilla/pat" ) @@ -14,12 +13,12 @@ type HookHandler struct { users database.UserManager repos database.RepoManager commits database.CommitManager + conf database.ConfigManager queue *queue.Queue - conf *config.Config } -func NewHookHandler(users database.UserManager, repos database.RepoManager, commits database.CommitManager, conf *config.Config, queue *queue.Queue) *HookHandler { - return &HookHandler{users, repos, commits, queue, conf} +func NewHookHandler(users database.UserManager, repos database.RepoManager, commits database.CommitManager, conf database.ConfigManager, queue *queue.Queue) *HookHandler { + return &HookHandler{users, repos, commits, conf, queue} } // PostHook receives a post-commit hook from GitHub, Bitbucket, etc @@ -28,7 +27,7 @@ func (h *HookHandler) PostHook(w http.ResponseWriter, r *http.Request) error { host := r.FormValue(":host") // get the remote system's client. - remote := h.conf.GetRemote(host) + remote := h.conf.Find().GetRemote(host) if remote == nil { return notFound{} } diff --git a/server/handler/login.go b/server/handler/login.go index 111b3b0a6..50783fa81 100644 --- a/server/handler/login.go +++ b/server/handler/login.go @@ -6,7 +6,6 @@ import ( "time" "github.com/drone/drone/server/database" - "github.com/drone/drone/server/resource/config" "github.com/drone/drone/server/session" "github.com/drone/drone/shared/model" "github.com/gorilla/pat" @@ -16,12 +15,12 @@ type LoginHandler struct { users database.UserManager repos database.RepoManager perms database.PermManager + conf database.ConfigManager sess session.Session - conf *config.Config } -func NewLoginHandler(users database.UserManager, repos database.RepoManager, perms database.PermManager, sess session.Session, conf *config.Config) *LoginHandler { - return &LoginHandler{users, repos, perms, sess, conf} +func NewLoginHandler(users database.UserManager, repos database.RepoManager, perms database.PermManager, sess session.Session, conf database.ConfigManager) *LoginHandler { + return &LoginHandler{users, repos, perms, conf, sess} } // GetLogin gets the login to the 3rd party remote system. @@ -30,7 +29,7 @@ func (h *LoginHandler) GetLogin(w http.ResponseWriter, r *http.Request) error { host := r.FormValue(":host") // get the remote system's client. - remote := h.conf.GetRemote(host) + remote := h.conf.Find().GetRemote(host) if remote == nil { return notFound{} } @@ -50,7 +49,7 @@ func (h *LoginHandler) GetLogin(w http.ResponseWriter, r *http.Request) error { if err != nil { // if self-registration is disabled we should // return a notAuthorized error - if !h.conf.Registration { + if !h.conf.Find().Registration { return notAuthorized{} } diff --git a/server/handler/repo.go b/server/handler/repo.go index c1a996d99..8a0b3b5c0 100644 --- a/server/handler/repo.go +++ b/server/handler/repo.go @@ -6,7 +6,6 @@ import ( "net/http" "github.com/drone/drone/server/database" - "github.com/drone/drone/server/resource/config" "github.com/drone/drone/server/session" "github.com/drone/drone/shared/httputil" "github.com/drone/drone/shared/sshutil" @@ -14,7 +13,7 @@ import ( ) type RepoHandler struct { - conf *config.Config + conf database.ConfigManager commits database.CommitManager perms database.PermManager repos database.RepoManager @@ -22,7 +21,7 @@ type RepoHandler struct { } func NewRepoHandler(repos database.RepoManager, commits database.CommitManager, - perms database.PermManager, sess session.Session, conf *config.Config) *RepoHandler { + perms database.PermManager, sess session.Session, conf database.ConfigManager) *RepoHandler { return &RepoHandler{conf, commits, perms, repos, sess} } @@ -87,7 +86,7 @@ func (h *RepoHandler) PostRepo(w http.ResponseWriter, r *http.Request) error { repo.PrivateKey = sshutil.MarshalPrivateKey(key) // get the remote and client - remote := h.conf.GetRemote(host) + remote := h.conf.Find().GetRemote(host) if remote == nil { return notFound{} } diff --git a/server/main.go b/server/main.go index 74eb0f051..6f09e3404 100644 --- a/server/main.go +++ b/server/main.go @@ -4,7 +4,11 @@ import ( "database/sql" "flag" "html/template" + "io/ioutil" "net/http" + "os" + "os/user" + "path/filepath" "runtime" "time" @@ -14,7 +18,6 @@ import ( "github.com/drone/drone/server/database/schema" "github.com/drone/drone/server/handler" "github.com/drone/drone/server/queue" - "github.com/drone/drone/server/resource/config" "github.com/drone/drone/server/session" "github.com/drone/drone/shared/build/docker" "github.com/drone/drone/shared/build/log" @@ -27,6 +30,9 @@ import ( ) var ( + // home directory for the application. + home string + // port the server will run on port string @@ -54,10 +60,6 @@ var ( workers int ) -// drone cofiguration data, loaded from the -// $HOME/.drone/config.toml file. -var conf config.Config - func main() { log.SetPriority(log.LOG_NOTICE) @@ -78,6 +80,7 @@ func main() { // template.New("_").Funcs(render.FuncMap).ParseGlob("template/html/*.html"), //).ExecuteTemplate + // load the html templates templateBox := rice.MustFindBox("template/html") templateFiles := []string{"login.html", "repo_branch.html", "repo_commit.html", "repo_conf.html", "repo_feed.html", "user_conf.html", "user_feed.html", "user_login.html", "user_repos.html", "404.html", "400.html"} templ := template.New("_").Funcs(funcMap) @@ -96,6 +99,7 @@ func main() { users := database.NewUserManager(db) perms := database.NewPermManager(db) commits := database.NewCommitManager(db) + configs := database.NewConfigManager(filepath.Join(home, "config.toml")) // cancel all previously running builds go commits.CancelAll() @@ -111,13 +115,13 @@ func main() { router := pat.New() handler.NewUsersHandler(users, sess).Register(router) handler.NewUserHandler(users, repos, commits, sess).Register(router) - handler.NewHookHandler(users, repos, commits, &conf, queue).Register(router) - handler.NewLoginHandler(users, repos, perms, sess, &conf).Register(router) + handler.NewHookHandler(users, repos, commits, configs, queue).Register(router) + handler.NewLoginHandler(users, repos, perms, sess, configs).Register(router) handler.NewCommitHandler(repos, commits, perms, sess, queue).Register(router) handler.NewBranchHandler(repos, commits, perms, sess).Register(router) - handler.NewRepoHandler(repos, commits, perms, sess, &conf).Register(router) + handler.NewRepoHandler(repos, commits, perms, sess, configs).Register(router) handler.NewBadgeHandler(repos, commits).Register(router) - handler.NewConfigHandler(conf, sess).Register(router) + handler.NewConfigHandler(configs, sess).Register(router) handler.NewSiteHandler(users, repos, commits, perms, sess, templ.ExecuteTemplate).Register(router) // serve static assets @@ -139,3 +143,74 @@ func main() { panic(http.ListenAndServe(port, nil)) } } + +// initialize the .drone directory and create a skeleton config +// file if one does not already exist. +func init() { + // load the current user + u, err := user.Current() + if err != nil { + panic(err) + } + + // set .drone home dir + home = filepath.Join(u.HomeDir, ".drone") + + // create the .drone home directory + os.MkdirAll(home, 0777) + + // check for the config file + filename := filepath.Join(u.HomeDir, ".drone", "config.toml") + if _, err := os.Stat(filename); err != nil { + // if not exists, create + ioutil.WriteFile(filename, []byte(defaultConfig), 0777) + } +} + +var defaultConfig = ` +# Enables user self-registration. If false, the system administrator +# will need to manually add users to the system. +registration = true + +[smtp] +host = "" +port = "" +from = "" +username = "" +password = "" + +[bitbucket] +url = "https://bitbucket.org" +api = "https://bitbucket.org" +client = "" +secret = "" +enabled = false + +[github] +url = "https://github.com" +api = "https://api.github.com" +client = "" +secret = "" +enabled = false + +[githubenterprise] +url = "" +api = "" +client = "" +secret = "" +enabled = false + +[gitlab] +url = "" +api = "" +client = "" +secret = "" +enabled = false + +[stash] +url = "" +api = "" +client = "" +secret = "" +enabled = false +` diff --git a/server/resource/config/manager.go b/server/resource/config/manager.go deleted file mode 100644 index 44defb53c..000000000 --- a/server/resource/config/manager.go +++ /dev/null @@ -1,34 +0,0 @@ -package config - -type ConfigManager interface { - Find() (*Config, error) - Must() *Config -} - -// configManager manages configuration data from a combination -// of command line args and .ini files. -type configManager struct { - dir string - conf *Config -} - -// NewManager initiales a new CommitManager intended to -// manage and persist commits. -func NewManager(dir string) ConfigManager { - conf := Config{} - //conf.Host = "localhost" - //conf.Scheme = "http" - return &configManager{dir, &conf} -} - -func (c *configManager) Find() (*Config, error) { - return nil, nil -} - -func (c *configManager) Must() *Config { - conf, err := c.Find() - if err != nil { - panic(err) - } - return conf -} diff --git a/server/resource/config/model.go b/server/resource/config/model.go deleted file mode 100644 index a6e9ebe6c..000000000 --- a/server/resource/config/model.go +++ /dev/null @@ -1,94 +0,0 @@ -package config - -import ( - "github.com/drone/drone/plugin/remote" - "github.com/drone/drone/plugin/remote/bitbucket" - "github.com/drone/drone/plugin/remote/github" - "github.com/drone/drone/plugin/remote/gitlab" - "github.com/drone/drone/plugin/remote/stash" - "github.com/drone/drone/plugin/smtp" -) - -type Config struct { - // Hostname of the server, eg drone.io - //Host string `json:"host"` - - // Scheme of the server, eg https - //Scheme string `json:"scheme"` - - // Registration with a value of True allows developers - // to register themselves. If false, must be approved - // or invited by the system administrator. - Registration bool `json:"registration"` - - // SMTP stores configuration details for connecting with - // and smtp server to send email notifications. - SMTP *smtp.SMTP `json:"smtp"` - - // Bitbucket stores configuration details for communicating - // with the bitbucket.org public cloud service. - Bitbucket *bitbucket.Bitbucket `json:"bitbucket"` - - // Github stores configuration details for communicating - // with the github.com public cloud service. - Github *github.Github `json:"github"` - - // GithubEnterprise stores configuration details for - // communicating with a private Github installation. - GithubEnterprise *github.Github `json:"githubEnterprise"` - - // Gitlab stores configuration details for communicating - // with a private gitlab installation. - Gitlab *gitlab.Gitlab `json:"gitlab"` - - // Stash stores configuration details for communicating - // with a private Atlassian Stash installation. - Stash *stash.Stash `json:"stash"` -} - -// GetRemote is a helper function that will return the -// remote plugin name based on the specified hostname. -func (c *Config) GetRemote(name string) remote.Remote { - // first attempt to get the remote instance - // by the unique plugin name (ie enterprise.github.com) - switch name { - case c.Github.GetName(): - return c.Github - case c.Bitbucket.GetName(): - return c.Bitbucket - case c.GithubEnterprise.GetName(): - return c.GithubEnterprise - case c.Gitlab.GetName(): - return c.Gitlab - case c.Stash.GetName(): - return c.Stash - } - - // else attempt to get the remote instance - // by the hostname (ie github.drone.io) - switch { - case c.Github.IsMatch(name): - return c.Github - case c.Bitbucket.IsMatch(name): - return c.Bitbucket - case c.GithubEnterprise.IsMatch(name): - return c.GithubEnterprise - case c.Gitlab.IsMatch(name): - return c.Gitlab - case c.Stash.IsMatch(name): - return c.Stash - } - - // else none found - return nil -} - -// GetClient is a helper function taht will return the named -// remote plugin client, used to interact with the remote system. -func (c *Config) GetClient(name, access, secret string) remote.Client { - remote := c.GetRemote(name) - if remote == nil { - return nil - } - return remote.GetClient(access, secret) -} diff --git a/server/resource/config/model_test.go b/server/resource/config/model_test.go deleted file mode 100644 index 8f7765bb6..000000000 --- a/server/resource/config/model_test.go +++ /dev/null @@ -1,39 +0,0 @@ -package config - -import ( - "fmt" - "testing" - - "github.com/BurntSushi/toml" -) - -func TestRead(t *testing.T) { - var data = ` -scheme = "https" -host = "localhost" -port = 8080 -open = true - -[github] -url = "https://github.com" -api = "https://api.github.com" - -[bitbucket] -url = "https://bitbucket.org" - -[smtp] -host = "smtp.drone.io" -port = "443" -user = "brad" -from = "brad@drone.io" - -` - - var conf Config - if _, err := toml.Decode(data, &conf); err != nil { - println(err.Error()) - return - } - - fmt.Printf("%#v\n", conf) -} diff --git a/shared/model/config.go b/shared/model/config.go index 8b5379070..f9c21fb09 100644 --- a/shared/model/config.go +++ b/shared/model/config.go @@ -1 +1,94 @@ package model + +import ( + "github.com/drone/drone/plugin/remote" + "github.com/drone/drone/plugin/remote/bitbucket" + "github.com/drone/drone/plugin/remote/github" + "github.com/drone/drone/plugin/remote/gitlab" + "github.com/drone/drone/plugin/remote/stash" + "github.com/drone/drone/plugin/smtp" +) + +type Config struct { + // Hostname of the server, eg drone.io + //Host string `json:"host"` + + // Scheme of the server, eg https + //Scheme string `json:"scheme"` + + // Registration with a value of True allows developers + // to register themselves. If false, must be approved + // or invited by the system administrator. + Registration bool `json:"registration"` + + // SMTP stores configuration details for connecting with + // and smtp server to send email notifications. + SMTP *smtp.SMTP `json:"smtp"` + + // Bitbucket stores configuration details for communicating + // with the bitbucket.org public cloud service. + Bitbucket *bitbucket.Bitbucket `json:"bitbucket"` + + // Github stores configuration details for communicating + // with the github.com public cloud service. + Github *github.Github `json:"github"` + + // GithubEnterprise stores configuration details for + // communicating with a private Github installation. + GithubEnterprise *github.Github `json:"githubEnterprise"` + + // Gitlab stores configuration details for communicating + // with a private gitlab installation. + Gitlab *gitlab.Gitlab `json:"gitlab"` + + // Stash stores configuration details for communicating + // with a private Atlassian Stash installation. + Stash *stash.Stash `json:"stash"` +} + +// GetRemote is a helper function that will return the +// remote plugin name based on the specified hostname. +func (c *Config) GetRemote(name string) remote.Remote { + // first attempt to get the remote instance + // by the unique plugin name (ie enterprise.github.com) + switch name { + case c.Github.GetName(): + return c.Github + case c.Bitbucket.GetName(): + return c.Bitbucket + case c.GithubEnterprise.GetName(): + return c.GithubEnterprise + case c.Gitlab.GetName(): + return c.Gitlab + case c.Stash.GetName(): + return c.Stash + } + + // else attempt to get the remote instance + // by the hostname (ie github.drone.io) + switch { + case c.Github.IsMatch(name): + return c.Github + case c.Bitbucket.IsMatch(name): + return c.Bitbucket + case c.GithubEnterprise.IsMatch(name): + return c.GithubEnterprise + case c.Gitlab.IsMatch(name): + return c.Gitlab + case c.Stash.IsMatch(name): + return c.Stash + } + + // else none found + return nil +} + +// GetClient is a helper function taht will return the named +// remote plugin client, used to interact with the remote system. +func (c *Config) GetClient(name, access, secret string) remote.Client { + remote := c.GetRemote(name) + if remote == nil { + return nil + } + return remote.GetClient(access, secret) +}