0
Fork 0
mirror of https://github.com/project-zot/zot.git synced 2025-01-20 22:52:51 -05:00

add debug flag for zli commands (#785)

Signed-off-by: Lisca Ana-Roberta <ana.kagome@yahoo.com>

Signed-off-by: Lisca Ana-Roberta <ana.kagome@yahoo.com>
This commit is contained in:
Lisca Ana-Roberta 2022-09-23 19:24:01 +03:00 committed by GitHub
parent 0f7b174fc0
commit 1bad90bb9d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 101 additions and 18 deletions

View file

@ -10,6 +10,7 @@ import (
"crypto/x509"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"net/url"
@ -66,7 +67,7 @@ func createHTTPClient(verifyTLS bool, host string) *http.Client {
}
func makeGETRequest(ctx context.Context, url, username, password string,
verifyTLS bool, resultsPtr interface{},
verifyTLS bool, debug bool, resultsPtr interface{}, configWriter io.Writer,
) (http.Header, error) {
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
if err != nil {
@ -75,11 +76,11 @@ func makeGETRequest(ctx context.Context, url, username, password string,
req.SetBasicAuth(username, password)
return doHTTPRequest(req, verifyTLS, resultsPtr)
return doHTTPRequest(req, verifyTLS, debug, resultsPtr, configWriter)
}
func makeGraphQLRequest(ctx context.Context, url, query, username,
password string, verifyTLS bool, resultsPtr interface{},
password string, verifyTLS bool, debug bool, resultsPtr interface{}, configWriter io.Writer,
) error {
req, err := http.NewRequestWithContext(ctx, "GET", url, bytes.NewBufferString(query))
if err != nil {
@ -94,7 +95,7 @@ func makeGraphQLRequest(ctx context.Context, url, query, username,
req.SetBasicAuth(username, password)
req.Header.Add("Content-Type", "application/json")
_, err = doHTTPRequest(req, verifyTLS, resultsPtr)
_, err = doHTTPRequest(req, verifyTLS, debug, resultsPtr, configWriter)
if err != nil {
return err
}
@ -102,7 +103,9 @@ func makeGraphQLRequest(ctx context.Context, url, query, username,
return nil
}
func doHTTPRequest(req *http.Request, verifyTLS bool, resultsPtr interface{}) (http.Header, error) {
func doHTTPRequest(req *http.Request, verifyTLS bool, debug bool,
resultsPtr interface{}, configWriter io.Writer,
) (http.Header, error) {
var httpClient *http.Client
host := req.Host
@ -119,11 +122,20 @@ func doHTTPRequest(req *http.Request, verifyTLS bool, resultsPtr interface{}) (h
httpClientLock.Unlock()
if debug {
fmt.Fprintln(configWriter, "[debug] ", req.Method, " ", req.URL, "[request header] ", req.Header)
}
resp, err := httpClient.Do(req)
if err != nil {
return nil, err
}
if debug {
fmt.Fprintln(configWriter, "[debug] ", req.Method, req.URL, "[status] ",
resp.StatusCode, " ", "[respoonse header] ", resp.Header)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
@ -252,7 +264,7 @@ func (p *requestsPool) doJob(ctx context.Context, job *manifestJob) {
defer p.wtgrp.Done()
header, err := makeGETRequest(ctx, job.url, job.username, job.password,
*job.config.verifyTLS, &job.manifestResp)
*job.config.verifyTLS, *job.config.debug, &job.manifestResp, job.config.resultWriter)
if err != nil {
if isContextDone(ctx) {
return

View file

@ -23,7 +23,7 @@ func NewCveCommand(searchService SearchService) *cobra.Command {
var servURL, user, outputFormat string
var isSpinner, verifyTLS, fixedFlag, verbose bool
var isSpinner, verifyTLS, fixedFlag, verbose, debug bool
cveCmd := &cobra.Command{
Use: "cve [config-name]",
@ -87,6 +87,7 @@ func NewCveCommand(searchService SearchService) *cobra.Command {
fixedFlag: &fixedFlag,
verifyTLS: &verifyTLS,
verbose: &verbose,
debug: &debug,
resultWriter: cmd.OutOrStdout(),
spinner: spinnerState{spin, isSpinner},
}
@ -109,6 +110,7 @@ func NewCveCommand(searchService SearchService) *cobra.Command {
user: &user,
outputFormat: &outputFormat,
fixedFlag: &fixedFlag,
debug: &debug,
}
setupCveFlags(cveCmd, vars)
@ -127,6 +129,7 @@ func setupCveFlags(cveCmd *cobra.Command, variables cveFlagVariables) {
" JSON and YAML format return all info for CVEs")
cveCmd.Flags().BoolVar(variables.fixedFlag, "fixed", false, "List tags which have fixed a CVE")
cveCmd.Flags().BoolVar(variables.debug, "debug", false, "Show debug output")
}
type cveFlagVariables struct {
@ -135,6 +138,7 @@ type cveFlagVariables struct {
user *string
outputFormat *string
fixedFlag *bool
debug *bool
}
type field struct {

View file

@ -152,6 +152,22 @@ func TestSearchCVECmd(t *testing.T) {
So(err, ShouldBeNil)
})
Convey("Test debug flag", t, func() {
args := []string{"cvetest", "--image", "dummyImageName:tag", "--debug"}
configPath := makeConfigFile(`{"configs":[{"_name":"cvetest","url":"https://test-url.com","showspinner":false}]}`)
defer os.Remove(configPath)
cmd := NewCveCommand(new(searchService))
buff := bytes.NewBufferString("")
cmd.SetOut(buff)
cmd.SetErr(buff)
cmd.SetArgs(args)
err := cmd.Execute()
space := regexp.MustCompile(`\s+`)
str := space.ReplaceAllString(buff.String(), " ")
So(strings.TrimSpace(str), ShouldContainSubstring, "GET")
So(err, ShouldNotBeNil)
})
Convey("Test CVE by name and CVE ID", t, func() {
args := []string{"cvetest", "--image", "dummyImageName", "--cve-id", "aCVEID", "--url", "someURL"}
configPath := makeConfigFile(`{"configs":[{"_name":"cvetest","showspinner":false}]}`)
@ -935,7 +951,7 @@ func MockNewCveCommand(searchService SearchService) *cobra.Command {
var servURL, user, outputFormat string
var verifyTLS, fixedFlag, verbose bool
var verifyTLS, fixedFlag, verbose, debug bool
cveCmd := &cobra.Command{
RunE: func(cmd *cobra.Command, args []string) error {
@ -974,6 +990,7 @@ func MockNewCveCommand(searchService SearchService) *cobra.Command {
}
verbose = false
debug = false
searchConfig := searchConfig{
params: searchCveParams,
@ -984,6 +1001,7 @@ func MockNewCveCommand(searchService SearchService) *cobra.Command {
fixedFlag: &fixedFlag,
verifyTLS: &verifyTLS,
verbose: &verbose,
debug: &debug,
resultWriter: cmd.OutOrStdout(),
}
@ -1005,6 +1023,7 @@ func MockNewCveCommand(searchService SearchService) *cobra.Command {
user: &user,
outputFormat: &outputFormat,
fixedFlag: &fixedFlag,
debug: &debug,
}
setupCveFlags(cveCmd, vars)

View file

@ -19,7 +19,7 @@ func NewImageCommand(searchService SearchService) *cobra.Command {
var servURL, user, outputFormat string
var isSpinner, verifyTLS, verbose bool
var isSpinner, verifyTLS, verbose, debug bool
imageCmd := &cobra.Command{
Use: "images [config-name]",
@ -78,6 +78,7 @@ func NewImageCommand(searchService SearchService) *cobra.Command {
user: &user,
outputFormat: &outputFormat,
verbose: &verbose,
debug: &debug,
spinner: spinnerState{spin, isSpinner},
verifyTLS: &verifyTLS,
resultWriter: cmd.OutOrStdout(),
@ -95,7 +96,7 @@ func NewImageCommand(searchService SearchService) *cobra.Command {
},
}
setupImageFlags(imageCmd, searchImageParams, &servURL, &user, &outputFormat, &verbose)
setupImageFlags(imageCmd, searchImageParams, &servURL, &user, &outputFormat, &verbose, &debug)
imageCmd.SetUsageTemplate(imageCmd.UsageTemplate() + usageFooter)
return imageCmd
@ -116,7 +117,7 @@ func parseBooleanConfig(configPath, configName, configParam string) (bool, error
}
func setupImageFlags(imageCmd *cobra.Command, searchImageParams map[string]*string,
servURL, user, outputFormat *string, verbose *bool,
servURL, user, outputFormat *string, verbose *bool, debug *bool,
) {
searchImageParams["imageName"] = imageCmd.Flags().StringP("name", "n", "", "List image details by name")
searchImageParams["digest"] = imageCmd.Flags().StringP("digest", "d", "",
@ -130,6 +131,7 @@ func setupImageFlags(imageCmd *cobra.Command, searchImageParams map[string]*stri
imageCmd.Flags().StringVarP(user, "user", "u", "", `User Credentials of zot server in "username:password" format`)
imageCmd.Flags().StringVarP(outputFormat, "output", "o", "", "Specify output format [text/json/yaml]")
imageCmd.Flags().BoolVar(verbose, "verbose", false, "Show verbose output")
imageCmd.Flags().BoolVar(debug, "debug", false, "Show debug output")
}
func searchImage(searchConfig searchConfig) error {

View file

@ -452,6 +452,24 @@ func TestListRepos(t *testing.T) {
So(err, ShouldBeNil)
})
Convey("Test listing repositories with debug flag", t, func() {
args := []string{"config-test", "--debug"}
configPath := makeConfigFile(`{"configs":[{"_name":"config-test","url":"https://test-url.com","showspinner":false}]}`)
defer os.Remove(configPath)
cmd := NewRepoCommand(new(searchService))
buff := bytes.NewBufferString("")
cmd.SetOut(buff)
cmd.SetErr(buff)
cmd.SetArgs(args)
err := cmd.Execute()
So(err, ShouldNotBeNil)
space := regexp.MustCompile(`\s+`)
str := space.ReplaceAllString(buff.String(), " ")
actual := strings.TrimSpace(str)
So(actual, ShouldContainSubstring, "GET")
})
Convey("Test error on home directory", t, func() {
args := []string{"config-test"}
@ -753,6 +771,26 @@ func TestServerResponseGQL(t *testing.T) {
So(actual, ShouldContainSubstring, "repo7 test:1.0 883fc0c5 3a1d2d0c 15B b8781e88 15B")
})
Convey("Test all images with debug flag", func() {
args := []string{"imagetest", "--debug"}
configPath := makeConfigFile(fmt.Sprintf(`{"configs":[{"_name":"imagetest","url":"%s","showspinner":false}]}`, url))
defer os.Remove(configPath)
cmd := NewImageCommand(new(searchService))
buff := bytes.NewBufferString("")
cmd.SetOut(buff)
cmd.SetErr(buff)
cmd.SetArgs(args)
err := cmd.Execute()
So(err, ShouldBeNil)
space := regexp.MustCompile(`\s+`)
str := space.ReplaceAllString(buff.String(), " ")
actual := strings.TrimSpace(str)
So(actual, ShouldContainSubstring, "GET")
So(actual, ShouldContainSubstring, "IMAGE NAME TAG DIGEST SIZE")
So(actual, ShouldContainSubstring, "repo7 test:2.0 883fc0c5 15B")
So(actual, ShouldContainSubstring, "repo7 test:1.0 883fc0c5 15B")
})
Convey("Test image by name config url", func() {
args := []string{"imagetest", "--name", "repo7"}
configPath := makeConfigFile(fmt.Sprintf(`{"configs":[{"_name":"imagetest","url":"%s","showspinner":false}]}`, url))
@ -1183,7 +1221,7 @@ func MockNewImageCommand(searchService SearchService) *cobra.Command {
var servURL, user, outputFormat string
var verifyTLS, verbose bool
var verifyTLS, verbose, debug bool
imageCmd := &cobra.Command{
RunE: func(cmd *cobra.Command, args []string) error {
@ -1228,6 +1266,7 @@ func MockNewImageCommand(searchService SearchService) *cobra.Command {
user: &user,
outputFormat: &outputFormat,
verbose: &verbose,
debug: &debug,
verifyTLS: &verifyTLS,
resultWriter: cmd.OutOrStdout(),
}
@ -1244,7 +1283,7 @@ func MockNewImageCommand(searchService SearchService) *cobra.Command {
},
}
setupImageFlags(imageCmd, searchImageParams, &servURL, &user, &outputFormat, &verbose)
setupImageFlags(imageCmd, searchImageParams, &servURL, &user, &outputFormat, &verbose, &debug)
imageCmd.SetUsageTemplate(imageCmd.UsageTemplate() + usageFooter)
return imageCmd

View file

@ -15,7 +15,7 @@ import (
func NewRepoCommand(searchService SearchService) *cobra.Command {
var servURL, user, outputFormat string
var isSpinner, verifyTLS, verbose bool
var isSpinner, verifyTLS, verbose, debug bool
repoCmd := &cobra.Command{
Use: "repos [config-name]",
@ -73,6 +73,7 @@ func NewRepoCommand(searchService SearchService) *cobra.Command {
user: &user,
outputFormat: &outputFormat,
verbose: &verbose,
debug: &debug,
spinner: spinnerState{spin, isSpinner},
verifyTLS: &verifyTLS,
resultWriter: cmd.OutOrStdout(),
@ -94,6 +95,7 @@ func NewRepoCommand(searchService SearchService) *cobra.Command {
repoCmd.Flags().StringVar(&servURL, "url", "", "Specify zot server URL if config-name is not mentioned")
repoCmd.Flags().StringVarP(&user, "user", "u", "", `User Credentials of zot server in "username:password" format`)
repoCmd.Flags().BoolVar(&debug, "debug", false, "Show debug output")
return repoCmd
}

View file

@ -85,6 +85,7 @@ type searchConfig struct {
verifyTLS *bool
fixedFlag *bool
verbose *bool
debug *bool
resultWriter io.Writer
spinner spinnerState
}

View file

@ -263,7 +263,8 @@ func (service searchService) getAllImages(ctx context.Context, config searchConf
return
}
_, err = makeGETRequest(ctx, catalogEndPoint, username, password, *config.verifyTLS, catalog)
_, err = makeGETRequest(ctx, catalogEndPoint, username, password, *config.verifyTLS,
*config.debug, catalog, config.resultWriter)
if err != nil {
if isContextDone(ctx) {
return
@ -306,7 +307,8 @@ func getImage(ctx context.Context, config searchConfig, username, password, imag
}
tagList := &tagListResp{}
_, err = makeGETRequest(ctx, tagListEndpoint, username, password, *config.verifyTLS, &tagList)
_, err = makeGETRequest(ctx, tagListEndpoint, username, password, *config.verifyTLS,
*config.debug, &tagList, config.resultWriter)
if err != nil {
if isContextDone(ctx) {
@ -658,7 +660,8 @@ func (service searchService) makeGraphQLQuery(ctx context.Context,
return err
}
err = makeGraphQLRequest(ctx, endPoint, query, username, password, *config.verifyTLS, resultPtr)
err = makeGraphQLRequest(ctx, endPoint, query, username, password, *config.verifyTLS,
*config.debug, resultPtr, config.resultWriter)
if err != nil {
return err
}
@ -1082,7 +1085,8 @@ func (service searchService) getRepos(ctx context.Context, config searchConfig,
return
}
_, err = makeGETRequest(ctx, catalogEndPoint, username, password, *config.verifyTLS, catalog)
_, err = makeGETRequest(ctx, catalogEndPoint, username, password, *config.verifyTLS,
*config.debug, catalog, config.resultWriter)
if err != nil {
if isContextDone(ctx) {
return