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  }