chore: use Docker Desktop proxy if available
used with ATOMIST_OFFLINE flag it allows to have all requests going through the configured proxy if any Signed-off-by: Yves Brissaud <yves.brissaud@docker.com>
This commit is contained in:
Родитель
00c5852290
Коммит
25765fd3ce
2
go.mod
2
go.mod
|
@ -3,6 +3,7 @@ module github.com/docker/index-cli-plugin
|
|||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/Microsoft/go-winio v0.5.2
|
||||
github.com/anchore/packageurl-go v0.1.1-0.20220428202044-a072fa3cb6d7
|
||||
github.com/anchore/stereoscope v0.0.0-20221006201143-d24c9d626b33
|
||||
github.com/anchore/syft v0.62.1
|
||||
|
@ -46,7 +47,6 @@ require (
|
|||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.1.1 // indirect
|
||||
github.com/Masterminds/sprig/v3 v3.2.2 // indirect
|
||||
github.com/Microsoft/go-winio v0.5.2 // indirect
|
||||
github.com/Microsoft/hcsshim v0.9.5 // indirect
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20220824120805-4b6e5c587895 // indirect
|
||||
github.com/acobaugh/osrelease v0.1.0 // indirect
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
package ddhttp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
var transport http.RoundTripper
|
||||
|
||||
func init() {
|
||||
// Check if we can discuss with the proxy socket from Docker Desktop.
|
||||
// If we can, it doesn't necessarily mean there a configured proxy.
|
||||
// But we delegate that management to Docker Desktop: if the socket is open, we connect to it. Docker Desktop can
|
||||
// then send the requests to a proxy or not, but that's Docker Desktop scope.
|
||||
// If we can't connect to the socket, then just use plain default transport.
|
||||
if !isDesktopHTTPProxyAvailable() {
|
||||
transport = http.DefaultTransport
|
||||
return
|
||||
}
|
||||
|
||||
transport = &http.Transport{
|
||||
Proxy: http.ProxyURL(&url.URL{
|
||||
Scheme: "http",
|
||||
}),
|
||||
DialContext: func(_ context.Context, _, _ string) (net.Conn, error) {
|
||||
return dialDesktopHTTPProxy()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func isDesktopHTTPProxyAvailable() bool {
|
||||
c, err := dialDesktopHTTPProxy()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
_ = c.Close()
|
||||
return true
|
||||
}
|
||||
|
||||
func DefaultClient() *http.Client {
|
||||
return &http.Client{
|
||||
Transport: transport,
|
||||
}
|
||||
}
|
||||
|
||||
func DefaultTransport() *http.Transport {
|
||||
if t, ok := transport.(*http.Transport); ok {
|
||||
return t
|
||||
}
|
||||
panic("could not get transport")
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package ddhttp
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os/user"
|
||||
"path"
|
||||
)
|
||||
|
||||
func dialDesktopHTTPProxy() (net.Conn, error) {
|
||||
current, err := user.Current()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
socket := path.Join(current.HomeDir, "Library/Containers/com.docker.docker/Data/httpproxy.sock")
|
||||
return net.Dial("unix", socket)
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package ddhttp
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os/user"
|
||||
"path"
|
||||
)
|
||||
|
||||
func dialDesktopHTTPProxy() (net.Conn, error) {
|
||||
current, err := user.Current()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
socket := path.Join(current.HomeDir, ".docker/desktop/httpproxy.sock")
|
||||
return net.Dial("unix", socket)
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package ddhttp
|
||||
|
||||
import (
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/Microsoft/go-winio"
|
||||
)
|
||||
|
||||
func dialDesktopHTTPProxy() (net.Conn, error) {
|
||||
timeout := time.Second
|
||||
return winio.DialPipe(`\\.\pipe\dockerHTTPProxy`, &timeout)
|
||||
}
|
|
@ -22,7 +22,6 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
|
@ -34,7 +33,7 @@ import (
|
|||
"olympos.io/encoding/edn"
|
||||
|
||||
"github.com/atomist-skills/go-skill"
|
||||
|
||||
"github.com/docker/index-cli-plugin/internal/ddhttp"
|
||||
"github.com/docker/index-cli-plugin/types"
|
||||
)
|
||||
|
||||
|
@ -94,7 +93,7 @@ func Detect(sb *types.Sbom, excludeSelf bool, workspace string, apiKey string) (
|
|||
func ForBaseImageInIndex(digest digest.Digest, workspace string, apiKey string) (*[]types.Image, error) {
|
||||
url := fmt.Sprintf("https://api.dso.docker.com/docker-images/chain-ids/%s.json", digest.String())
|
||||
|
||||
resp, err := http.Get(url)
|
||||
resp, err := ddhttp.DefaultClient().Get(url)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to query index")
|
||||
}
|
||||
|
@ -243,7 +242,7 @@ func ForBaseImageInGraphQL(cfg *v1.ConfigFile) (*types.BaseImagesByDiffIdsQuery,
|
|||
}
|
||||
|
||||
url := "https://api.dso.docker.com/v1/graphql"
|
||||
client := graphql.NewClient(url, nil)
|
||||
client := graphql.NewClient(url, ddhttp.DefaultClient())
|
||||
variables := map[string]interface{}{
|
||||
"diffIds": diffIds,
|
||||
}
|
||||
|
@ -270,7 +269,7 @@ func ForBaseImageInGraphQL(cfg *v1.ConfigFile) (*types.BaseImagesByDiffIdsQuery,
|
|||
|
||||
func ForImageInGraphQL(sb *types.Sbom) (*types.ImageByDigestQuery, error) {
|
||||
url := "https://api.dso.docker.com/v1/graphql"
|
||||
client := graphql.NewClient(url, nil)
|
||||
client := graphql.NewClient(url, ddhttp.DefaultClient())
|
||||
variables := map[string]interface{}{
|
||||
"digest": sb.Source.Image.Digest,
|
||||
"os": sb.Source.Image.Platform.Os,
|
||||
|
|
|
@ -24,14 +24,13 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/hasura/go-graphql-client"
|
||||
|
||||
"github.com/docker/index-cli-plugin/internal"
|
||||
"github.com/docker/index-cli-plugin/types"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"olympos.io/encoding/edn"
|
||||
|
||||
"github.com/atomist-skills/go-skill"
|
||||
"github.com/docker/index-cli-plugin/internal"
|
||||
"github.com/docker/index-cli-plugin/internal/ddhttp"
|
||||
"github.com/docker/index-cli-plugin/types"
|
||||
)
|
||||
|
||||
type CveResult struct {
|
||||
|
@ -115,7 +114,7 @@ func query(query string, name string, workspace string, apiKey string) (*http.Re
|
|||
}
|
||||
query = fmt.Sprintf(`{:queries [{:name "query" :query %s}]}`, query)
|
||||
skill.Log.Debugf("Query %s", query)
|
||||
client := &http.Client{}
|
||||
client := ddhttp.DefaultClient()
|
||||
req, err := http.NewRequest(http.MethodPost, url, strings.NewReader(query))
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to create http request")
|
||||
|
@ -139,7 +138,7 @@ func query(query string, name string, workspace string, apiKey string) (*http.Re
|
|||
|
||||
func ForVulnerabilitiesInGraphQL(sb *types.Sbom) (*types.VulnerabilitiesByPurls, error) {
|
||||
url := "https://api.dso.docker.com/v1/graphql"
|
||||
client := graphql.NewClient(url, nil)
|
||||
client := graphql.NewClient(url, ddhttp.DefaultClient())
|
||||
|
||||
purls := make([]string, 0)
|
||||
for _, p := range sb.Artifacts {
|
||||
|
|
|
@ -26,10 +26,6 @@ import (
|
|||
|
||||
stereoscopeimage "github.com/anchore/stereoscope/pkg/image"
|
||||
"github.com/anchore/syft/syft/source"
|
||||
"github.com/atomist-skills/go-skill"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/docker/index-cli-plugin/internal"
|
||||
"github.com/dustin/go-humanize"
|
||||
"github.com/google/go-containerregistry/pkg/authn"
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
|
@ -41,6 +37,12 @@ import (
|
|||
"github.com/google/go-containerregistry/pkg/v1/tarball"
|
||||
"github.com/google/uuid"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/atomist-skills/go-skill"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/docker/index-cli-plugin/internal"
|
||||
"github.com/docker/index-cli-plugin/internal/ddhttp"
|
||||
)
|
||||
|
||||
type ImageId struct {
|
||||
|
@ -287,7 +289,7 @@ func SaveImage(image string, username string, password string, cli command.Cli)
|
|||
}, nil
|
||||
}
|
||||
// try remote image next
|
||||
desc, err := remote.Get(ref, WithAuth(username, password))
|
||||
desc, err := remote.Get(ref, WithAuth(username, password), remote.WithTransport(ddhttp.DefaultTransport()))
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to pull image: %s", image)
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче