// HomeHandler is the main home screen func HomeHandler(w http.ResponseWriter, r *http.Request) { c, err := goship.ParseETCD(etcd.NewClient([]string{*ETCDServer})) if err != nil { log.Printf("Failed to Parse to ETCD data %s", err) http.Error(w, err.Error(), http.StatusInternalServerError) } u, err := getUser(r) if err != nil { log.Println("Failed to get User! ") http.Error(w, err.Error(), http.StatusUnauthorized) } t, err := template.New("index.html").ParseFiles("templates/index.html", "templates/base.html") if err != nil { log.Printf("Failed to parse template: %s", err) http.Error(w, err.Error(), http.StatusInternalServerError) } c.Projects = removeUnauthorizedProjects(c.Projects, r, u) sort.Sort(ByName(c.Projects)) // apply each plugin for _, pl := range plugin.Plugins { err := pl.Apply(c) if err != nil { log.Printf("Failed to apply plugin: %s", err) http.Error(w, err.Error(), http.StatusInternalServerError) } } js, css := getAssetsTemplates() gt := os.Getenv(gitHubAPITokenEnvVar) pt := c.Pivotal.Token t.ExecuteTemplate(w, "base", map[string]interface{}{"Javascript": js, "Stylesheet": css, "Projects": c.Projects, "User": u, "Page": "home", "ConfirmDeployFlag": *confirmDeployFlag, "GithubToken": gt, "PivotalToken": pt}) }
func TestCanParseETCD(t *testing.T) { got, err := goship.ParseETCD(&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 TestCleanProjects(t *testing.T) { authentication.authorization = true req, _ := http.NewRequest("GET", "", nil) p, err := goship.ParseETCD(&MockEtcdClient{}) if err != nil { t.Fatalf("Can't parse %s %s", t, err) } u := User{} u.UserName = "******" got := len(p.Projects) if got < 1 { t.Errorf("clean projects test expects projects to have at least one project [%d]", got) } got = len(removeUnauthorizedProjects(p.Projects, req, u)) if got != 0 { t.Errorf("clean projects failed to clean project for unauth user.. [%d]", got) } }
func ProjCommitsHandler(w http.ResponseWriter, r *http.Request, projName string) { c, err := goship.ParseETCD(etcd.NewClient([]string{*ETCDServer})) if err != nil { log.Println("ERROR: Parsing etc ", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } u, err := getUser(r) if err != nil { log.Println("ERROR: Getting User", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } proj, err := goship.ProjectFromName(c.Projects, projName) if err != nil { log.Println("ERROR: Getting Project from name", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } // Remove projects that the user is not a collaborator on... fp := removeUnauthorizedProjects([]goship.Project{*proj}, r, u) p, err := retrieveCommits(r, fp[0], c.DeployUser) if err != nil { log.Println("ERROR: Retrieving Commits ", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } j, err := json.Marshal(p) if err != nil { log.Println("ERROR: Marshalling Retrieving Commits ", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") _, err = w.Write(j) if err != nil { log.Println("ERROR: ", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } }
func (h ProjCommitsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request, projName string) { c, err := goship.ParseETCD(h.ecl) if err != nil { log.Println("ERROR: Parsing etc ", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } u, err := auth.CurrentUser(r) if err != nil { log.Println("ERROR: Getting User", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } proj, err := goship.ProjectFromName(c.Projects, projName) if err != nil { log.Println("ERROR: Getting Project from name", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } // Remove projects that the user is not a collaborator on... fp := acl.ReadableProjects(h.ac, []goship.Project{*proj}, u) p, err := retrieveCommits(h.gcl, h.ac, r, fp[0], c.DeployUser) if err != nil { log.Println("ERROR: Retrieving Commits ", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } j, err := json.Marshal(p) if err != nil { log.Println("ERROR: Marshalling Retrieving Commits ", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") _, err = w.Write(j) if err != nil { log.Println("ERROR: ", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } }
func extractDeployLogHandler(fn func(http.ResponseWriter, *http.Request, string, goship.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 := goship.ParseETCD(etcd.NewClient([]string{*ETCDServer})) if err != nil { log.Println("ERROR: ", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } // auth check for user u, err := getUser(r) if err != nil { log.Println("Failed to get a user while deploying in Auth Mode! ") http.Error(w, err.Error(), http.StatusUnauthorized) } c.Projects = removeUnauthorizedProjects(c.Projects, r, 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 := goship.EnvironmentFromName(c.Projects, projectName, environmentName) if err != nil { log.Println("ERROR: Can't get environment from name", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } fn(w, r, m[2], *e, projectName) } }
func DeployHandler(w http.ResponseWriter, r *http.Request) { c, err := goship.ParseETCD(etcd.NewClient([]string{*ETCDServer})) if err != nil { log.Println("ERROR: ", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } u, err := getUser(r) if err != nil { log.Println("Failed to get a User! ") http.Error(w, err.Error(), http.StatusUnauthorized) } user := u.UserName 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 { log.Println("Error: ", err.Error()) } } deployTime := time.Now() success := true command, err := getDeployCommand(c.Projects, p, env) if err != nil { log.Println("ERROR: ", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } cmd := exec.Command(command[0], command[1:]...) stdout, err := cmd.StdoutPipe() if err != nil { log.Println("ERROR: could not get stdout of command:" + err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } stderr, err := cmd.StderrPipe() if err != nil { log.Println("ERROR: could not get stderr of command:" + err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } if err = cmd.Start(); err != nil { log.Println("ERROR: could not run deployment command: " + err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } var wg sync.WaitGroup wg.Add(2) go sendOutput(&wg, bufio.NewScanner(stdout), p, env, deployTime) go sendOutput(&wg, bufio.NewScanner(stderr), p, env, deployTime) wg.Wait() err = cmd.Wait() if err != nil { success = false log.Println("Deployment failed: " + err.Error()) } if c.Notify != "" { err = endNotify(c.Notify, p, env, success) if err != nil { log.Println("Error: ", err.Error()) } } if (c.Pivotal.Token != "") && (c.Pivotal.Project != "") && success { err := goship.PostToPivotal(c.Pivotal, env, owner, name, toRevision, fromRevision) if err != nil { log.Println("ERROR: ", err) } else { log.Printf("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 { log.Println("ERROR: ", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } }