mirror of
https://github.com/project-zot/zot.git
synced 2024-12-30 22:34:13 -05:00
fix(cli): do not show signatures and fix tls verification client side (#904)
Issues fixed: - the cli calls reaching out to the catalog endpoint used to request signature manifests - resty was used instead of the cli http client to check if the discovery api was available but it did not take into account TLS verification configuration (testing locally withself-signed certificates did not work) (cherry picked from commit ca42031ae9b1ceb459f5cd4f86cb82b3c9f78157) Signed-off-by: Andrei Aaron <andaaron@cisco.com>
This commit is contained in:
parent
ac6c6a844c
commit
1d9c88c313
4 changed files with 111 additions and 71 deletions
|
@ -4,19 +4,14 @@
|
|||
package cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/briandowns/spinner"
|
||||
"github.com/spf13/cobra"
|
||||
"gopkg.in/resty.v1"
|
||||
|
||||
zotErrors "zotregistry.io/zot/errors"
|
||||
"zotregistry.io/zot/pkg/api/constants"
|
||||
)
|
||||
|
||||
func NewCveCommand(searchService SearchService) *cobra.Command {
|
||||
|
@ -142,74 +137,10 @@ type cveFlagVariables struct {
|
|||
debug *bool
|
||||
}
|
||||
|
||||
type field struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type schemaList struct {
|
||||
Data struct {
|
||||
Schema struct {
|
||||
QueryType struct {
|
||||
Fields []field `json:"fields"`
|
||||
} `json:"queryType"` //nolint:tagliatelle // graphQL schema
|
||||
} `json:"__schema"` //nolint:tagliatelle // graphQL schema
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
func containsGQLQuery(queryList []field, query string) bool {
|
||||
for _, q := range queryList {
|
||||
if q.Name == query {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func checkExtEndPoint(serverURL string) bool {
|
||||
client := resty.New()
|
||||
|
||||
extEndPoint, err := combineServerAndEndpointURL(serverURL, fmt.Sprintf("%s%s",
|
||||
constants.RoutePrefix, constants.ExtOciDiscoverPrefix))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
//nolint: gosec
|
||||
resp, err := client.R().Get(extEndPoint)
|
||||
if err != nil || resp.StatusCode() != http.StatusOK {
|
||||
return false
|
||||
}
|
||||
|
||||
searchEndPoint, _ := combineServerAndEndpointURL(serverURL, constants.FullSearchPrefix)
|
||||
|
||||
query := `
|
||||
{
|
||||
__schema() {
|
||||
queryType {
|
||||
fields {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
resp, err = client.R().Get(searchEndPoint + "?query=" + url.QueryEscape(query))
|
||||
if err != nil || resp.StatusCode() != http.StatusOK {
|
||||
return false
|
||||
}
|
||||
|
||||
queryList := &schemaList{}
|
||||
|
||||
_ = json.Unmarshal(resp.Body(), queryList)
|
||||
|
||||
return containsGQLQuery(queryList.Data.Schema.QueryType.Fields, "ImageList")
|
||||
}
|
||||
|
||||
func searchCve(searchConfig searchConfig) error {
|
||||
var searchers []searcher
|
||||
|
||||
if checkExtEndPoint(*searchConfig.servURL) {
|
||||
if checkExtEndPoint(searchConfig) {
|
||||
searchers = getCveSearchersGQL()
|
||||
} else {
|
||||
searchers = getCveSearchers()
|
||||
|
|
100
pkg/cli/discover.go
Normal file
100
pkg/cli/discover.go
Normal file
|
@ -0,0 +1,100 @@
|
|||
//go:build search
|
||||
// +build search
|
||||
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
distext "github.com/opencontainers/distribution-spec/specs-go/v1/extensions"
|
||||
|
||||
"zotregistry.io/zot/pkg/api/constants"
|
||||
)
|
||||
|
||||
type field struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type schemaList struct {
|
||||
Data struct {
|
||||
Schema struct {
|
||||
QueryType struct {
|
||||
Fields []field `json:"fields"`
|
||||
} `json:"queryType"` //nolint:tagliatelle // graphQL schema
|
||||
} `json:"__schema"` //nolint:tagliatelle // graphQL schema
|
||||
} `json:"data"`
|
||||
Errors []errorGraphQL `json:"errors"`
|
||||
}
|
||||
|
||||
func containsGQLQuery(queryList []field, query string) bool {
|
||||
for _, q := range queryList {
|
||||
if q.Name == query {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func checkExtEndPoint(config searchConfig) bool {
|
||||
username, password := getUsernameAndPassword(*config.user)
|
||||
ctx := context.Background()
|
||||
|
||||
discoverEndPoint, err := combineServerAndEndpointURL(*config.servURL, fmt.Sprintf("%s%s",
|
||||
constants.RoutePrefix, constants.ExtOciDiscoverPrefix))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
discoverResponse := &distext.ExtensionList{}
|
||||
|
||||
_, err = makeGETRequest(ctx, discoverEndPoint, username, password, *config.verifyTLS,
|
||||
*config.debug, &discoverResponse, config.resultWriter)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
searchEnabled := false
|
||||
|
||||
for _, extension := range discoverResponse.Extensions {
|
||||
if extension.Name == "_zot" {
|
||||
for _, endpoint := range extension.Endpoints {
|
||||
if endpoint == constants.FullSearchPrefix {
|
||||
searchEnabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !searchEnabled {
|
||||
return false
|
||||
}
|
||||
|
||||
searchEndPoint, _ := combineServerAndEndpointURL(*config.servURL, constants.FullSearchPrefix)
|
||||
|
||||
query := `
|
||||
{
|
||||
__schema() {
|
||||
queryType {
|
||||
fields {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
queryResponse := &schemaList{}
|
||||
|
||||
err = makeGraphQLRequest(ctx, searchEndPoint, query, username, password, *config.verifyTLS,
|
||||
*config.debug, queryResponse, config.resultWriter)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if err = checkResultGraphQLQuery(ctx, err, queryResponse.Errors); err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return containsGQLQuery(queryResponse.Data.Schema.QueryType.Fields, "ImageList")
|
||||
}
|
|
@ -138,7 +138,7 @@ func setupImageFlags(imageCmd *cobra.Command, searchImageParams map[string]*stri
|
|||
func searchImage(searchConfig searchConfig) error {
|
||||
var searchers []searcher
|
||||
|
||||
if checkExtEndPoint(*searchConfig.servURL) {
|
||||
if checkExtEndPoint(searchConfig) {
|
||||
searchers = getImageSearchersGQL()
|
||||
} else {
|
||||
searchers = getImageSearchers()
|
||||
|
|
|
@ -324,6 +324,15 @@ func getImage(ctx context.Context, config searchConfig, username, password, imag
|
|||
}
|
||||
|
||||
for _, tag := range tagList.Tags {
|
||||
hasTagPrefix := strings.HasPrefix(tag, "sha256-")
|
||||
hasTagSuffix := strings.HasSuffix(tag, ".sig")
|
||||
|
||||
// check if it's an image or a signature
|
||||
// we don't want to show signatures in cli responses
|
||||
if hasTagPrefix && hasTagSuffix {
|
||||
continue
|
||||
}
|
||||
|
||||
wtgrp.Add(1)
|
||||
|
||||
go addManifestCallToPool(ctx, config, pool, username, password, imageName, tag, rch, wtgrp)
|
||||
|
|
Loading…
Reference in a new issue