2016-04-02 14:40:07 +02:00
package projects
2016-04-04 15:44:34 +02:00
import (
2016-04-09 21:09:57 +02:00
"database/sql"
2017-02-23 00:21:49 +01:00
"net/http"
2016-07-01 01:54:09 +02:00
"os"
"strconv"
2016-04-09 21:09:57 +02:00
2017-02-23 06:12:16 +01:00
"github.com/ansible-semaphore/semaphore/db"
2019-07-09 14:56:03 +02:00
"github.com/ansible-semaphore/semaphore/util"
2019-07-09 18:11:01 +02:00
"github.com/ansible-semaphore/semaphore/mulekick"
2017-02-23 00:21:49 +01:00
"github.com/gorilla/context"
2016-04-04 15:44:34 +02:00
"github.com/masterminds/squirrel"
)
2016-04-02 14:40:07 +02:00
2017-02-23 06:12:16 +01:00
func clearRepositoryCache ( repository db . Repository ) error {
2016-07-01 01:54:09 +02:00
repoName := "repository_" + strconv . Itoa ( repository . ID )
repoPath := util . Config . TmpPath + "/" + repoName
_ , err := os . Stat ( repoPath )
if err == nil {
return os . RemoveAll ( repoPath )
}
return nil
}
2018-03-27 22:12:47 +02:00
// RepositoryMiddleware ensures a repository exists and loads it to the context
2019-07-09 18:11:01 +02:00
func RepositoryMiddleware ( w http . ResponseWriter , r * http . Request ) {
project := context . Get ( r , "project" ) . ( db . Project )
repositoryID , err := util . GetIntParam ( "repository_id" , w , r )
if err != nil {
return
}
2019-07-09 14:56:03 +02:00
2019-07-09 18:11:01 +02:00
var repository db . Repository
if err := db . Mysql . SelectOne ( & repository , "select * from project__repository where project_id=? and id=?" , project . ID , repositoryID ) ; err != nil {
if err == sql . ErrNoRows {
w . WriteHeader ( http . StatusNotFound )
return
2019-07-09 14:56:03 +02:00
}
2016-04-09 21:09:57 +02:00
2019-07-09 18:11:01 +02:00
panic ( err )
}
2019-07-09 14:56:03 +02:00
2019-07-09 18:11:01 +02:00
context . Set ( r , "repository" , repository )
2016-04-02 14:40:07 +02:00
}
2018-03-27 22:12:47 +02:00
// GetRepositories returns all repositories in a project sorted by type
2019-07-09 18:11:01 +02:00
func GetRepositories ( w http . ResponseWriter , r * http . Request ) {
project := context . Get ( r , "project" ) . ( db . Project )
var repos [ ] db . Repository
2016-04-04 15:44:34 +02:00
2019-07-09 18:11:01 +02:00
sort := r . URL . Query ( ) . Get ( "sort" )
order := r . URL . Query ( ) . Get ( "order" )
2017-03-16 16:31:34 +01:00
2019-07-09 18:11:01 +02:00
if order != asc && order != desc {
order = asc
}
2017-03-16 16:31:34 +01:00
2019-07-09 18:11:01 +02:00
q := squirrel . Select ( "pr.id" ,
2017-03-16 16:31:34 +01:00
"pr.name" ,
"pr.project_id" ,
"pr.git_url" ,
"pr.ssh_key_id" ,
"pr.removed" ) .
From ( "project__repository pr" )
2019-07-09 18:11:01 +02:00
switch sort {
case "name" , "git_url" :
q = q . Where ( "pr.project_id=?" , project . ID ) .
OrderBy ( "pr." + sort + " " + order )
case "ssh_key" :
q = q . LeftJoin ( "access_key ak ON (pr.ssh_key_id = ak.id)" ) .
Where ( "pr.project_id=?" , project . ID ) .
OrderBy ( "ak.name " + order )
default :
q = q . Where ( "pr.project_id=?" , project . ID ) .
OrderBy ( "pr.name " + order )
}
2017-03-16 16:31:34 +01:00
2019-07-09 18:11:01 +02:00
query , args , err := q . ToSql ( )
util . LogWarning ( err )
2016-04-04 15:44:34 +02:00
2019-07-09 18:11:01 +02:00
if _ , err := db . Mysql . Select ( & repos , query , args ... ) ; err != nil {
panic ( err )
}
2016-04-04 15:44:34 +02:00
2019-07-09 18:11:01 +02:00
mulekick . WriteJSON ( w , http . StatusOK , repos )
2016-04-04 15:44:34 +02:00
}
2018-03-27 22:12:47 +02:00
// AddRepository creates a new repository in the database
2019-07-09 18:11:01 +02:00
func AddRepository ( w http . ResponseWriter , r * http . Request ) {
project := context . Get ( r , "project" ) . ( db . Project )
2016-04-04 15:44:34 +02:00
2019-07-09 18:11:01 +02:00
var repository struct {
Name string ` json:"name" binding:"required" `
GitURL string ` json:"git_url" binding:"required" `
SSHKeyID int ` json:"ssh_key_id" binding:"required" `
}
if err := mulekick . Bind ( w , r , & repository ) ; err != nil {
return
}
2016-04-04 15:44:34 +02:00
2019-07-09 18:11:01 +02:00
res , err := db . Mysql . Exec ( "insert into project__repository set project_id=?, git_url=?, ssh_key_id=?, name=?" , project . ID , repository . GitURL , repository . SSHKeyID , repository . Name )
if err != nil {
panic ( err )
}
2016-04-17 12:41:36 +02:00
2019-07-09 18:11:01 +02:00
insertID , err := res . LastInsertId ( )
util . LogWarning ( err )
insertIDInt := int ( insertID )
objType := "repository"
desc := "Repository (" + repository . GitURL + ") created"
if err := ( db . Event {
ProjectID : & project . ID ,
ObjectType : & objType ,
ObjectID : & insertIDInt ,
Description : & desc ,
} . Insert ( ) ) ; err != nil {
panic ( err )
}
2016-04-04 15:44:34 +02:00
2019-07-09 18:11:01 +02:00
w . WriteHeader ( http . StatusNoContent )
2016-04-04 15:44:34 +02:00
}
2018-03-27 22:12:47 +02:00
// UpdateRepository updates the values of a repository in the database
2019-07-09 18:11:01 +02:00
func UpdateRepository ( w http . ResponseWriter , r * http . Request ) {
oldRepo := context . Get ( r , "repository" ) . ( db . Repository )
var repository struct {
Name string ` json:"name" binding:"required" `
GitURL string ` json:"git_url" binding:"required" `
SSHKeyID int ` json:"ssh_key_id" binding:"required" `
}
if err := mulekick . Bind ( w , r , & repository ) ; err != nil {
return
}
2016-04-17 12:41:36 +02:00
2019-07-09 18:11:01 +02:00
if _ , err := db . Mysql . Exec ( "update project__repository set name=?, git_url=?, ssh_key_id=? where id=?" , repository . Name , repository . GitURL , repository . SSHKeyID , oldRepo . ID ) ; err != nil {
panic ( err )
}
2016-07-01 01:54:09 +02:00
2019-07-09 18:11:01 +02:00
if oldRepo . GitURL != repository . GitURL {
util . LogWarning ( clearRepositoryCache ( oldRepo ) )
}
2019-07-09 14:56:03 +02:00
2019-07-09 18:11:01 +02:00
desc := "Repository (" + repository . GitURL + ") updated"
objType := "inventory"
if err := ( db . Event {
ProjectID : & oldRepo . ProjectID ,
Description : & desc ,
ObjectID : & oldRepo . ID ,
ObjectType : & objType ,
} . Insert ( ) ) ; err != nil {
panic ( err )
}
2016-04-09 21:09:57 +02:00
2019-07-09 18:11:01 +02:00
w . WriteHeader ( http . StatusNoContent )
2016-04-02 14:40:07 +02:00
}
2018-03-27 22:12:47 +02:00
// RemoveRepository deletes a repository from a project in the database
2019-07-09 18:11:01 +02:00
func RemoveRepository ( w http . ResponseWriter , r * http . Request ) {
repository := context . Get ( r , "repository" ) . ( db . Repository )
2016-06-17 22:16:46 +02:00
2019-07-09 18:11:01 +02:00
templatesC , err := db . Mysql . SelectInt ( "select count(1) from project__template where project_id=? and repository_id=?" , repository . ProjectID , repository . ID )
if err != nil {
panic ( err )
}
2019-07-09 14:56:03 +02:00
2019-07-09 18:11:01 +02:00
if templatesC > 0 {
if len ( r . URL . Query ( ) . Get ( "setRemoved" ) ) == 0 {
mulekick . WriteJSON ( w , http . StatusBadRequest , map [ string ] interface { } {
"error" : "Repository is in use by one or more templates" ,
"templatesUse" : true ,
} )
2019-07-09 14:56:03 +02:00
2016-06-17 22:16:46 +02:00
return
}
2019-07-09 18:11:01 +02:00
if _ , err := db . Mysql . Exec ( "update project__repository set removed=1 where id=?" , repository . ID ) ; err != nil {
2016-06-17 22:16:46 +02:00
panic ( err )
}
2019-07-09 18:11:01 +02:00
w . WriteHeader ( http . StatusNoContent )
return
}
if _ , err := db . Mysql . Exec ( "delete from project__repository where id=?" , repository . ID ) ; err != nil {
panic ( err )
}
2016-04-04 15:44:34 +02:00
2019-07-09 18:11:01 +02:00
util . LogWarning ( clearRepositoryCache ( repository ) )
2016-07-01 01:54:09 +02:00
2019-07-09 18:11:01 +02:00
desc := "Repository (" + repository . GitURL + ") deleted"
if err := ( db . Event {
ProjectID : & repository . ProjectID ,
Description : & desc ,
} . Insert ( ) ) ; err != nil {
panic ( err )
}
2016-04-17 12:41:36 +02:00
2019-07-09 18:11:01 +02:00
w . WriteHeader ( http . StatusNoContent )
2016-04-02 14:40:07 +02:00
}