github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/api/resourceserver/versionserver/list.go (about) 1 package versionserver 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 "strconv" 8 "strings" 9 10 "code.cloudfoundry.org/lager" 11 "github.com/pf-qiu/concourse/v6/atc" 12 "github.com/pf-qiu/concourse/v6/atc/api/accessor" 13 "github.com/pf-qiu/concourse/v6/atc/api/present" 14 "github.com/pf-qiu/concourse/v6/atc/db" 15 ) 16 17 func (s *Server) ListResourceVersions(pipeline db.Pipeline) http.Handler { 18 logger := s.logger.Session("list-resource-versions") 19 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 20 var ( 21 err error 22 from int 23 to int 24 limit int 25 ) 26 27 err = r.ParseForm() 28 if err != nil { 29 logger.Error("failed-to-parse-request-form", err) 30 w.WriteHeader(http.StatusInternalServerError) 31 return 32 } 33 34 fields := r.Form["filter"] 35 versionFilter := make(atc.Version) 36 for _, field := range fields { 37 vs := strings.SplitN(field, ":", 2) 38 if len(vs) == 2 { 39 versionFilter[vs[0]] = vs[1] 40 } 41 } 42 43 resourceName := r.FormValue(":resource_name") 44 teamName := r.FormValue(":team_name") 45 46 urlFrom := r.FormValue(atc.PaginationQueryFrom) 47 urlTo := r.FormValue(atc.PaginationQueryTo) 48 49 urlLimit := r.FormValue(atc.PaginationQueryLimit) 50 51 limit, _ = strconv.Atoi(urlLimit) 52 if limit == 0 { 53 limit = atc.PaginationAPIDefaultLimit 54 } 55 56 page := db.Page{Limit: limit} 57 if urlFrom != "" { 58 from, _ = strconv.Atoi(urlFrom) 59 page.From = db.NewIntPtr(from) 60 } 61 if urlTo != "" { 62 to, _ = strconv.Atoi(urlTo) 63 page.To = db.NewIntPtr(to) 64 } 65 66 resource, found, err := pipeline.Resource(resourceName) 67 if err != nil { 68 logger.Error("failed-to-get-resource", err, lager.Data{"resource-name": resourceName}) 69 w.WriteHeader(http.StatusInternalServerError) 70 return 71 } 72 73 if !found { 74 logger.Info("resource-not-found", lager.Data{"resource-name": resourceName}) 75 w.WriteHeader(http.StatusNotFound) 76 return 77 } 78 79 versions, pagination, found, err := resource.Versions(page, versionFilter) 80 if err != nil { 81 logger.Error("failed-to-get-resource-config-versions", err) 82 w.WriteHeader(http.StatusInternalServerError) 83 return 84 } 85 86 if !found { 87 logger.Info("resource-versions-not-found", lager.Data{"resource-name": resourceName}) 88 w.WriteHeader(http.StatusNotFound) 89 return 90 } 91 92 pipelineRef := atc.PipelineRef{ 93 Name: pipeline.Name(), 94 InstanceVars: pipeline.InstanceVars(), 95 } 96 if pagination.Older != nil { 97 s.addNextLink(w, teamName, pipelineRef, resourceName, *pagination.Older) 98 } 99 100 if pagination.Newer != nil { 101 s.addPreviousLink(w, teamName, pipelineRef, resourceName, *pagination.Newer) 102 } 103 104 w.Header().Set("Content-Type", "application/json") 105 106 w.WriteHeader(http.StatusOK) 107 108 acc := accessor.GetAccessor(r) 109 hideMetadata := !resource.Public() && !acc.IsAuthorized(teamName) 110 111 versions = present.ResourceVersions(hideMetadata, versions) 112 113 err = json.NewEncoder(w).Encode(versions) 114 if err != nil { 115 logger.Error("failed-to-encode-resource-versions", err) 116 w.WriteHeader(http.StatusInternalServerError) 117 } 118 }) 119 } 120 121 func (s *Server) addNextLink(w http.ResponseWriter, teamName string, pipelineRef atc.PipelineRef, resourceName string, page db.Page) { 122 if pipelineRef.InstanceVars != nil { 123 w.Header().Add("Link", fmt.Sprintf( 124 `<%s/api/v1/teams/%s/pipelines/%s/resources/%s/versions?%s=%d&%s=%d&%s>; rel="%s"`, 125 s.externalURL, 126 teamName, 127 pipelineRef.Name, 128 resourceName, 129 atc.PaginationQueryTo, 130 *page.To, 131 atc.PaginationQueryLimit, 132 page.Limit, 133 pipelineRef.QueryParams().Encode(), 134 atc.LinkRelNext, 135 )) 136 } else { 137 w.Header().Add("Link", fmt.Sprintf( 138 `<%s/api/v1/teams/%s/pipelines/%s/resources/%s/versions?%s=%d&%s=%d>; rel="%s"`, 139 s.externalURL, 140 teamName, 141 pipelineRef.Name, 142 resourceName, 143 atc.PaginationQueryTo, 144 *page.To, 145 atc.PaginationQueryLimit, 146 page.Limit, 147 atc.LinkRelNext, 148 )) 149 } 150 } 151 152 func (s *Server) addPreviousLink(w http.ResponseWriter, teamName string, pipelineRef atc.PipelineRef, resourceName string, page db.Page) { 153 if pipelineRef.InstanceVars != nil { 154 w.Header().Add("Link", fmt.Sprintf( 155 `<%s/api/v1/teams/%s/pipelines/%s/resources/%s/versions?%s=%d&%s=%d&%s>; rel="%s"`, 156 s.externalURL, 157 teamName, 158 pipelineRef.Name, 159 resourceName, 160 atc.PaginationQueryFrom, 161 *page.From, 162 atc.PaginationQueryLimit, 163 page.Limit, 164 pipelineRef.QueryParams().Encode(), 165 atc.LinkRelPrevious, 166 )) 167 } else { 168 w.Header().Add("Link", fmt.Sprintf( 169 `<%s/api/v1/teams/%s/pipelines/%s/resources/%s/versions?%s=%d&%s=%d>; rel="%s"`, 170 s.externalURL, 171 teamName, 172 pipelineRef.Name, 173 resourceName, 174 atc.PaginationQueryFrom, 175 *page.From, 176 atc.PaginationQueryLimit, 177 page.Limit, 178 atc.LinkRelPrevious, 179 )) 180 } 181 }