github.com/jenkins-x/jx/v2@v2.1.155/pkg/cmd/get/get_limits.go (about)

     1  package get
     2  
     3  import (
     4  	"github.com/jenkins-x/jx/v2/pkg/cmd/helper"
     5  	"github.com/spf13/cobra"
     6  
     7  	"encoding/json"
     8  	"fmt"
     9  	"net/http"
    10  
    11  	"github.com/jenkins-x/jx/v2/pkg/cmd/opts"
    12  	"github.com/jenkins-x/jx/v2/pkg/cmd/templates"
    13  
    14  	"strconv"
    15  	"time"
    16  
    17  	"github.com/jenkins-x/jx-logging/pkg/log"
    18  )
    19  
    20  type RateLimits struct {
    21  	Resources RateResources `json:"resources"`
    22  }
    23  
    24  type RateResources struct {
    25  	Core    Rate `json:"core"`
    26  	Search  Rate `json:"search"`
    27  	GraphQL Rate `json:"graphql"`
    28  }
    29  
    30  type Rate struct {
    31  	Limit     int `json:"limit"`
    32  	Remaining int `json:"remaining"`
    33  	Reset     int `json:"reset"`
    34  }
    35  
    36  // GetAddonOptions the command line options
    37  type GetLimitsOptions struct {
    38  	Options
    39  }
    40  
    41  var (
    42  	get_limits_long = templates.LongDesc(`
    43  		Display the github limits for users
    44  
    45  `)
    46  
    47  	get_limits_example = templates.Examples(`
    48  		# List all git users with limits
    49  		jx get limits
    50  	`)
    51  )
    52  
    53  // NewCmdGetLimits creates the command
    54  func NewCmdGetLimits(commonOpts *opts.CommonOptions) *cobra.Command {
    55  	options := &GetLimitsOptions{
    56  		Options: Options{
    57  			CommonOptions: commonOpts,
    58  		},
    59  	}
    60  
    61  	cmd := &cobra.Command{
    62  		Use:     "limits [flags]",
    63  		Short:   "Displays the git user limits",
    64  		Long:    get_limits_long,
    65  		Example: get_limits_example,
    66  		Aliases: []string{"limit"},
    67  		Run: func(cmd *cobra.Command, args []string) {
    68  			options.Cmd = cmd
    69  			options.Args = args
    70  			err := options.Run()
    71  			helper.CheckErr(err)
    72  		},
    73  	}
    74  
    75  	return cmd
    76  }
    77  
    78  // Run implements this command
    79  func (o *GetLimitsOptions) Run() error {
    80  	authConfigSvc, err := o.GitAuthConfigService()
    81  	if err != nil {
    82  		return err
    83  	}
    84  	config := authConfigSvc.Config()
    85  
    86  	table := o.CreateTable()
    87  	table.AddRow("Name", "URL", "Username", "Limit", "Remaining", "Reset")
    88  
    89  	for _, s := range config.Servers {
    90  		kind := s.Kind
    91  		if kind == "" {
    92  			kind = "github"
    93  		}
    94  
    95  		if kind == "github" {
    96  			for _, u := range s.Users {
    97  				r, err := o.GetLimits(s.URL, u.Username, u.ApiToken)
    98  				if err != nil {
    99  					return err
   100  				}
   101  
   102  				resetLabel := ""
   103  				if 0 != r.Resources.Core.Reset {
   104  					secondsUntilReset := int64(r.Resources.Core.Reset) - time.Now().Unix()
   105  					d := time.Duration(1000 * 1000 * 1000 * secondsUntilReset)
   106  					resetLabel = d.String()
   107  				}
   108  
   109  				table.AddRow(s.Name, s.URL, u.Username, strconv.Itoa(r.Resources.Core.Limit), strconv.Itoa(r.Resources.Core.Remaining), resetLabel)
   110  			}
   111  		}
   112  
   113  	}
   114  	table.Render()
   115  
   116  	return nil
   117  }
   118  
   119  func (o *GetLimitsOptions) GetLimits(server string, username string, apitoken string) (RateLimits, error) {
   120  	url := fmt.Sprintf("https://%s:%s@api.github.com/rate_limit", username, apitoken)
   121  
   122  	// Build the request
   123  	req, err := http.NewRequest("GET", url, nil)
   124  	if err != nil {
   125  		log.Logger().Errorf("NewRequest: %s", err)
   126  		return RateLimits{}, err
   127  	}
   128  
   129  	// For control over HTTP client headers,
   130  	// redirect policy, and other settings,
   131  	// create a Client
   132  	// A Client is an HTTP client
   133  	client := &http.Client{}
   134  
   135  	// Send the request via a client
   136  	// Do sends an HTTP request and
   137  	// returns an HTTP response
   138  	resp, err := client.Do(req)
   139  	if err != nil {
   140  		log.Logger().Errorf("Do: %s", err)
   141  		return RateLimits{}, err
   142  	}
   143  
   144  	// Callers should close resp.Body
   145  	// when done reading from it
   146  	// Defer the closing of the body
   147  	defer resp.Body.Close()
   148  
   149  	// Fill the record with the data from the JSON
   150  	var limits RateLimits
   151  
   152  	// Use json.Decode for reading streams of JSON data
   153  	if err := json.NewDecoder(resp.Body).Decode(&limits); err != nil {
   154  		log.Logger().Errorf("Decode: %s", err)
   155  	}
   156  
   157  	return limits, nil
   158  }