package server import ( "fmt" "net/url" "github.com/gorilla/mux" "github.com/pkg/errors" "github.com/runatlantis/atlantis/server/events/command" ) // Router can be used to retrieve Atlantis URLs. It acts as an intermediary // between the underlying router and the rest of Atlantis that might need to // construct URLs to different resources. type Router struct { // Underlying is the router that the routes have been constructed on. Underlying *mux.Router // LockViewRouteName is the named route for the lock view that can be Get'd // from the Underlying router. LockViewRouteName string // ProjectJobsViewRouteName is the named route for the projects active jobs ProjectJobsViewRouteName string // LockViewRouteIDQueryParam is the query parameter needed to construct the // lock view: underlying.Get(LockViewRouteName).URL(LockViewRouteIDQueryParam, "my id"). LockViewRouteIDQueryParam string // AtlantisURL is the fully qualified URL that Atlantis is // accessible from externally. AtlantisURL *url.URL } // GenerateLockURL returns a fully qualified URL to view the lock at lockID. func (r *Router) GenerateLockURL(lockID string) string { lockURL, _ := r.Underlying.Get(r.LockViewRouteName).URL(r.LockViewRouteIDQueryParam, url.QueryEscape(lockID)) // At this point, lockURL will just be a path because r.Underlying isn't // configured with host or scheme information. So to generate the fully // qualified LockURL we just append the router's url to our base url. // We're not doing anything fancy here with the actual url object because // golang likes to double escape the lockURL path when using url.Parse(). return r.AtlantisURL.String() + lockURL.String() } func (r *Router) GenerateProjectJobURL(ctx command.ProjectContext) (string, error) { if ctx.JobID == "" { return "", fmt.Errorf("no job id in ctx") } jobURL, err := r.Underlying.Get((r.ProjectJobsViewRouteName)).URL( "job-id", ctx.JobID, ) if err != nil { return "", errors.Wrapf(err, "creating job url for %s", ctx.JobID) } return r.AtlantisURL.String() + jobURL.String(), nil } func (r *Router) GenerateProjectWorkflowHookURL(hookID string) (string, error) { jobURL, err := r.Underlying.Get((r.ProjectJobsViewRouteName)).URL( "job-id", hookID, ) if err != nil { return "", errors.Wrapf(err, "creating workflow hook url for %s", hookID) } return r.AtlantisURL.String() + jobURL.String(), nil }