github.com/netdata/go.d.plugin@v0.58.1/modules/dockerhub/apiclient.go (about)

     1  // SPDX-License-Identifier: GPL-3.0-or-later
     2  
     3  package dockerhub
     4  
     5  import (
     6  	"encoding/json"
     7  	"fmt"
     8  	"io"
     9  	"net/http"
    10  	"net/url"
    11  	"path"
    12  
    13  	"github.com/netdata/go.d.plugin/pkg/web"
    14  )
    15  
    16  type repository struct {
    17  	User        string
    18  	Name        string
    19  	Status      int
    20  	StarCount   int    `json:"star_count"`
    21  	PullCount   int    `json:"pull_count"`
    22  	LastUpdated string `json:"last_updated"`
    23  }
    24  
    25  func newAPIClient(client *http.Client, request web.Request) *apiClient {
    26  	return &apiClient{httpClient: client, request: request}
    27  }
    28  
    29  type apiClient struct {
    30  	httpClient *http.Client
    31  	request    web.Request
    32  }
    33  
    34  func (a apiClient) getRepository(repoName string) (*repository, error) {
    35  	req, err := a.createRequest(repoName)
    36  	if err != nil {
    37  		return nil, fmt.Errorf("error on creating http request : %v", err)
    38  	}
    39  
    40  	resp, err := a.doRequestOK(req)
    41  	defer closeBody(resp)
    42  	if err != nil {
    43  		return nil, err
    44  	}
    45  
    46  	var repo repository
    47  	if err := json.NewDecoder(resp.Body).Decode(&repo); err != nil {
    48  		return nil, fmt.Errorf("error on parsing response from %s : %v", req.URL, err)
    49  	}
    50  
    51  	return &repo, nil
    52  }
    53  
    54  func (a apiClient) doRequestOK(req *http.Request) (*http.Response, error) {
    55  	resp, err := a.httpClient.Do(req)
    56  	if err != nil {
    57  		return nil, fmt.Errorf("error on request: %v", err)
    58  	}
    59  
    60  	if resp.StatusCode != http.StatusOK {
    61  		return resp, fmt.Errorf("%s returned HTTP status %d", req.URL, resp.StatusCode)
    62  	}
    63  	return resp, nil
    64  }
    65  
    66  func (a apiClient) createRequest(urlPath string) (*http.Request, error) {
    67  	req := a.request.Copy()
    68  	u, err := url.Parse(req.URL)
    69  	if err != nil {
    70  		return nil, err
    71  	}
    72  
    73  	u.Path = path.Join(u.Path, urlPath)
    74  	req.URL = u.String()
    75  	return web.NewHTTPRequest(req)
    76  }
    77  
    78  func closeBody(resp *http.Response) {
    79  	if resp != nil && resp.Body != nil {
    80  		_, _ = io.Copy(io.Discard, resp.Body)
    81  		_ = resp.Body.Close()
    82  	}
    83  }