func (h HomeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { c, err := config.Load(h.ecl) if err != nil { glog.Errorf("Failed to Parse to ETCD data %s", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } u, err := auth.CurrentUser(r) if err != nil { glog.Errorf("Failed to get current user: %v", err) http.Error(w, err.Error(), http.StatusUnauthorized) return } t, err := template.New("index.html").ParseFiles("templates/index.html", "templates/base.html") if err != nil { glog.Errorf("Failed to parse template: %v", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } projs := acl.ReadableProjects(h.ac, c.Projects, u) sort.Sort(ByName(c.Projects)) // columns maps a plugin name to a list of columns columns := make(map[string][]plugin.Column) for _, pl := range plugin.Plugins { for _, p := range c.Projects { cols, err := pl.Apply(p) if err != nil { glog.Errorf("Failed to apply plugin: %s", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } columns[p.Name] = append(columns[p.Name], cols...) } } js, css := h.assets.Templates() gt := os.Getenv(gitHubAPITokenEnvVar) pt := c.Pivotal.Token params := map[string]interface{}{ "Javascript": js, "Stylesheet": css, "Projects": projs, "PluginColumns": columns, "User": u, "Page": "home", "ConfirmDeployFlag": *confirmDeployFlag, "GithubToken": gt, "PivotalToken": pt, } helpers.RespondWithTemplate(w, "text/html", t, "base", params) }
func TestLoad(t *testing.T) { got, err := config.Load(&MockEtcdClient{}) if err != nil { t.Fatalf("Can't parse %s %s", t, err) } compareStrings("deploy user", got.DeployUser, "test_user", t) compareStrings("token", got.Pivotal.Token, "XXXXXX", t) compareStrings("project", got.Pivotal.Project, "111111", t) compareStrings("project name", got.Projects[0].Name, "pivotal_project", t) compareStrings("repo path", got.Projects[0].Environments[0].RepoPath, "/repos/test_repo_name/.git", t) compareStrings("repo branch", got.Projects[0].Environments[0].Branch, "master", t) compareStrings("host name", got.Projects[0].Environments[0].Hosts[0].URI, "test-qa-01.somewhere.com", t) }
func (h handler) loadProject(projName string, u auth.User) (p config.Project, deployUser string, err error) { c, err := config.Load(h.ecl) if err != nil { glog.Errorf("Parsing etc: %v", err) return config.Project{}, "", err } p, err = config.ProjectFromName(c.Projects, projName) if err != nil { glog.Errorf("Failed to get project from name: %v", err) return config.Project{}, "", err } if !h.ac.Readable(p.RepoOwner, p.RepoName, u.Name) { return config.Project{}, "", projectUnaccessible } return p, c.DeployUser, nil }
func extractDeployLogHandler(ac acl.AccessControl, ecl *etcd.Client, fn func(http.ResponseWriter, *http.Request, string, config.Environment, string)) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { m := validPathWithEnv.FindStringSubmatch(r.URL.Path) if m == nil { http.NotFound(w, r) return } c, err := config.Load(ecl) if err != nil { glog.Errorf("Failed to get current configuration: %v", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } // auth check for user u, err := auth.CurrentUser(r) if err != nil { glog.Error("Failed to get a user while deploying in Auth Mode: %v", err) http.Error(w, err.Error(), http.StatusUnauthorized) } c.Projects = acl.ReadableProjects(ac, c.Projects, u) // get project name and env from url a := strings.Split(m[2], "-") l := len(a) environmentName := a[l-1] var projectName string if m[1] == "commits" { projectName = m[2] } else { projectName = strings.Join(a[0:l-1], "-") } e, err := config.EnvironmentFromName(c.Projects, projectName, environmentName) if err != nil { glog.Errorf("Can't get environment from name: %v", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } fn(w, r, m[2], *e, projectName) } }
func main() { flag.Parse() conf := parseConfig() if *skipUpdate == false { updateChefRepo(conf) } if *pullOnly == false { c, err := gsconfig.Load(etcd.NewClient([]string{conf.etcdServer})) if err != nil { glog.Fatalf("Error parsing ETCD: %s", err) } projectEnv, err := gsconfig.EnvironmentFromName(c.Projects, *deployProj, *deployEnv) if err != nil { glog.Fatalf("Error getting project %s %s %s", *deployProj, *deployEnv, err) } glog.Infof("Deploying project name: %s environment Name: %s", *deployEnv, projectEnv.Name) servers := projectEnv.Hosts var d, e string if *chefRunlist != "" { e = " -o \"" + *chefRunlist + "\" " } for _, h := range servers { if *bootstrap == true { d = "knife solo bootstrap -c " + conf.knifePath + " -i " + conf.pemKey + " --no-host-key-verify " + e + conf.deployUser + "@" + h.URI } else { d = "knife solo cook -c " + conf.knifePath + " -i " + conf.pemKey + " --no-host-key-verify " + e + conf.deployUser + "@" + h.URI } glog.Infof("Deploying to server: %s", h.URI) glog.Infof("Preparing Knife command: %s", d) _, err := execCmd(d, conf) if err != nil { glog.Fatalf("Error Executing command %s", err) } } } }
func (h DeployHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { c, err := config.Load(h.ecl) if err != nil { glog.Errorf("Failed to fetch latest configuration: %v", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } u, err := auth.CurrentUser(r) if err != nil { glog.Errorf("Failed to fetch current user: %v", err) http.Error(w, err.Error(), http.StatusUnauthorized) return } user := u.Name p := r.FormValue("project") env := r.FormValue("environment") fromRevision := r.FormValue("from_revision") toRevision := r.FormValue("to_revision") owner := r.FormValue("repo_owner") name := r.FormValue("repo_name") if c.Notify != "" { err := startNotify(c.Notify, user, p, env) if err != nil { glog.Errorf("Failed to notify start-deployment event of %s (%s): %v", p, env, err) } } deployTime := time.Now() success := true command, err := getDeployCommand(c.Projects, p, env) if err != nil { glog.Errorf("Failed to fetch deploy command: %v", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } cmd := exec.Command(command[0], command[1:]...) stdout, err := cmd.StdoutPipe() if err != nil { glog.Errorf("Could not get stdout of command: %v", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } stderr, err := cmd.StderrPipe() if err != nil { glog.Errorf("Could not get stderr of command: %v", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } glog.Infof("Starting deployment of %s-%s (%s/%s) from %s to %s; requested by %s", p, env, owner, name, fromRevision, toRevision, user) if err = cmd.Start(); err != nil { glog.Errorf("Could not run deployment command: %v", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } var wg sync.WaitGroup wg.Add(2) go h.sendOutput(&wg, bufio.NewScanner(stdout), p, env, deployTime) go h.sendOutput(&wg, bufio.NewScanner(stderr), p, env, deployTime) wg.Wait() err = cmd.Wait() if err != nil { success = false glog.Errorf("Deployment of %s failed: %v", p, err) } else { glog.Infof("Successfully deployed %s", p) } if c.Notify != "" { err = endNotify(c.Notify, p, env, success) if err != nil { glog.Errorf("Failed to notify start-deployment event of %s (%s): %v", p, env, err) } } if (c.Pivotal.Token != "") && (c.Pivotal.Project != "") && success { err := config.PostToPivotal(c.Pivotal, env, owner, name, toRevision, fromRevision) if err != nil { glog.Errorf("Failed to post to pivotal: %v", err) } else { glog.Infof("Pivotal Info: %s %s", c.Pivotal.Token, c.Pivotal.Project) } } err = insertEntry(fmt.Sprintf("%s-%s", p, env), owner, name, fromRevision, toRevision, user, success, deployTime) if err != nil { glog.Errorf("Failed to insert an entry: %v", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } }