Moved imported orca docs into ucp directory
							parent
							
								
									a56d36fdaa
								
							
						
					
					
						commit
						b2da4f338c
					
				| 
						 | 
				
			
			@ -1,42 +0,0 @@
 | 
			
		|||
package mock
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/docker/orca"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"net/url"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type (
 | 
			
		||||
	MockRegistry struct {
 | 
			
		||||
		orca.RegistryConfig
 | 
			
		||||
		client *orca.RegistryClient
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func NewRegistry(reg *orca.RegistryConfig) (orca.Registry, error) {
 | 
			
		||||
	u, err := url.Parse(reg.URL)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	rClient := &orca.RegistryClient{
 | 
			
		||||
		URL: u,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &MockRegistry{
 | 
			
		||||
		RegistryConfig: *reg,
 | 
			
		||||
		client:         rClient,
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *MockRegistry) GetAuthToken(username, accessType, hostname, reponame string) (string, error) {
 | 
			
		||||
	return "foo", nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *MockRegistry) GetConfig() *orca.RegistryConfig {
 | 
			
		||||
	return &r.RegistryConfig
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *MockRegistry) GetTransport() http.RoundTripper {
 | 
			
		||||
	return r.client.HttpClient.Transport
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,18 +0,0 @@
 | 
			
		|||
# Docker Registry Go lib
 | 
			
		||||
This is a simple Go package to use with the Docker Registry v1.
 | 
			
		||||
 | 
			
		||||
# Example
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
import registry "github.com/ehazlett/orca/registry/v1"
 | 
			
		||||
 | 
			
		||||
// make sure to handle the err
 | 
			
		||||
client, _ := registry.NewRegistryClient("http://localhost:5000", nil)
 | 
			
		||||
 | 
			
		||||
res, _ := client.Search("busybox", 1, 100)
 | 
			
		||||
 | 
			
		||||
fmt.Printf("Number of Repositories: %d\n", res.NumberOfResults)
 | 
			
		||||
for _, r := range res.Results {
 | 
			
		||||
	fmt.Printf(" -  Name: %s\n", r.Name)
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
| 
						 | 
				
			
			@ -1,15 +0,0 @@
 | 
			
		|||
package v1
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Error struct {
 | 
			
		||||
	StatusCode int
 | 
			
		||||
	Status     string
 | 
			
		||||
	msg        string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e Error) Error() string {
 | 
			
		||||
	return fmt.Sprintf("%s: %s", e.Status, e.msg)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,277 +0,0 @@
 | 
			
		|||
package v1
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"crypto/tls"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"net"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"path"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	log "github.com/Sirupsen/logrus"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	ErrNotFound        = errors.New("Not found")
 | 
			
		||||
	defaultHTTPTimeout = 30 * time.Second
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type RegistryClient struct {
 | 
			
		||||
	URL        *url.URL
 | 
			
		||||
	tlsConfig  *tls.Config
 | 
			
		||||
	httpClient *http.Client
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Repo struct {
 | 
			
		||||
	Namespace  string
 | 
			
		||||
	Repository string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func parseRepo(repo string) Repo {
 | 
			
		||||
	namespace := "library"
 | 
			
		||||
	r := repo
 | 
			
		||||
 | 
			
		||||
	if strings.Index(repo, "/") != -1 {
 | 
			
		||||
		parts := strings.Split(repo, "/")
 | 
			
		||||
		namespace = parts[0]
 | 
			
		||||
		r = path.Join(parts[1:]...)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return Repo{
 | 
			
		||||
		Namespace:  namespace,
 | 
			
		||||
		Repository: r,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newHTTPClient(u *url.URL, tlsConfig *tls.Config, timeout time.Duration) *http.Client {
 | 
			
		||||
	httpTransport := &http.Transport{
 | 
			
		||||
		TLSClientConfig: tlsConfig,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	httpTransport.Dial = func(proto, addr string) (net.Conn, error) {
 | 
			
		||||
		return net.DialTimeout(proto, addr, timeout)
 | 
			
		||||
	}
 | 
			
		||||
	return &http.Client{Transport: httpTransport}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewRegistryClient(registryUrl string, tlsConfig *tls.Config) (*RegistryClient, error) {
 | 
			
		||||
	u, err := url.Parse(registryUrl)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	httpClient := newHTTPClient(u, tlsConfig, defaultHTTPTimeout)
 | 
			
		||||
	return &RegistryClient{
 | 
			
		||||
		URL:        u,
 | 
			
		||||
		httpClient: httpClient,
 | 
			
		||||
		tlsConfig:  tlsConfig,
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (client *RegistryClient) doRequest(method string, path string, body []byte, headers map[string]string) ([]byte, error) {
 | 
			
		||||
	b := bytes.NewBuffer(body)
 | 
			
		||||
 | 
			
		||||
	req, err := http.NewRequest(method, client.URL.String()+"/v1"+path, b)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	req.Header.Add("Content-Type", "application/json")
 | 
			
		||||
	if headers != nil {
 | 
			
		||||
		for header, value := range headers {
 | 
			
		||||
			req.Header.Add(header, value)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	resp, err := client.httpClient.Do(req)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		if !strings.Contains(err.Error(), "connection refused") && client.tlsConfig == nil {
 | 
			
		||||
			return nil, fmt.Errorf("%v. Are you trying to connect to a TLS-enabled endpoint without TLS?", err)
 | 
			
		||||
		}
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	defer resp.Body.Close()
 | 
			
		||||
 | 
			
		||||
	data, err := ioutil.ReadAll(resp.Body)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if resp.StatusCode == 404 {
 | 
			
		||||
		return nil, ErrNotFound
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if resp.StatusCode >= 400 {
 | 
			
		||||
		return nil, Error{StatusCode: resp.StatusCode, Status: resp.Status, msg: string(data)}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return data, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (client *RegistryClient) Search(query string, page int, numResults int) (*SearchResult, error) {
 | 
			
		||||
	if numResults < 1 {
 | 
			
		||||
		numResults = 100
 | 
			
		||||
	}
 | 
			
		||||
	uri := fmt.Sprintf("/search?q=%s&n=%d&page=%d", query, numResults, page)
 | 
			
		||||
	data, err := client.doRequest("GET", uri, nil, nil)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	res := &SearchResult{}
 | 
			
		||||
	if err := json.Unmarshal(data, &res); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return res, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (client *RegistryClient) DeleteRepository(repo string) error {
 | 
			
		||||
	r := parseRepo(repo)
 | 
			
		||||
	uri := fmt.Sprintf("/repositories/%s/%s/", r.Namespace, r.Repository)
 | 
			
		||||
	if _, err := client.doRequest("DELETE", uri, nil, nil); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (client *RegistryClient) DeleteTag(repo string, tag string) error {
 | 
			
		||||
	r := parseRepo(repo)
 | 
			
		||||
	uri := fmt.Sprintf("/repositories/%s/%s/tags/%s", r.Namespace, r.Repository, tag)
 | 
			
		||||
	if _, err := client.doRequest("DELETE", uri, nil, nil); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (client *RegistryClient) Layer(id string) (*Layer, error) {
 | 
			
		||||
	uri := fmt.Sprintf("/images/%s/json", id)
 | 
			
		||||
	data, err := client.doRequest("GET", uri, nil, nil)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	layer := &Layer{}
 | 
			
		||||
	if err := json.Unmarshal(data, &layer); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return layer, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (client *RegistryClient) loadLayer(name, id string) ([]Layer, []Tag, int64, error) {
 | 
			
		||||
	uri := fmt.Sprintf("/images/%s/json", id)
 | 
			
		||||
	layer := Layer{}
 | 
			
		||||
	layers := []Layer{}
 | 
			
		||||
	tags := []Tag{}
 | 
			
		||||
	size := int64(0)
 | 
			
		||||
 | 
			
		||||
	data, err := client.doRequest("GET", uri, nil, nil)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, nil, -1, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := json.Unmarshal(data, &layer); err != nil {
 | 
			
		||||
		return nil, nil, -1, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	uri = fmt.Sprintf("/images/%s/ancestry", id)
 | 
			
		||||
 | 
			
		||||
	ancestry := []string{}
 | 
			
		||||
 | 
			
		||||
	data, err = client.doRequest("GET", uri, nil, nil)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, nil, -1, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err = json.Unmarshal(data, &ancestry); err != nil {
 | 
			
		||||
		return nil, nil, -1, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tag := Tag{
 | 
			
		||||
		ID:   id,
 | 
			
		||||
		Name: name,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tags = append(tags, tag)
 | 
			
		||||
	layer.Ancestry = ancestry
 | 
			
		||||
 | 
			
		||||
	layers = append(layers, layer)
 | 
			
		||||
	// parse ancestor layers
 | 
			
		||||
	for _, i := range ancestry {
 | 
			
		||||
		uri = fmt.Sprintf("/images/%s/json", i)
 | 
			
		||||
		l := &Layer{}
 | 
			
		||||
 | 
			
		||||
		data, err = client.doRequest("GET", uri, nil, nil)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, nil, -1, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if err = json.Unmarshal(data, &l); err != nil {
 | 
			
		||||
			return nil, nil, -1, err
 | 
			
		||||
		}
 | 
			
		||||
		size += l.Size
 | 
			
		||||
		layers = append(layers, *l)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return layers, tags, size, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (client *RegistryClient) Repository(name string) (*Repository, error) {
 | 
			
		||||
	r := parseRepo(name)
 | 
			
		||||
	uri := fmt.Sprintf("/repositories/%s/%s/tags", r.Namespace, r.Repository)
 | 
			
		||||
 | 
			
		||||
	repository := &Repository{
 | 
			
		||||
		Name:       path.Join(r.Namespace, r.Repository),
 | 
			
		||||
		Namespace:  r.Namespace,
 | 
			
		||||
		Repository: r.Repository,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// HACK: check for hub url and return
 | 
			
		||||
	// used in orca catalog
 | 
			
		||||
	baseURL := client.URL.String()
 | 
			
		||||
	if strings.Contains(baseURL, "index.docker.io") {
 | 
			
		||||
		return repository, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var repoTags map[string]string
 | 
			
		||||
 | 
			
		||||
	data, err := client.doRequest("GET", uri, nil, nil)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := json.Unmarshal(data, &repoTags); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	layers := []Layer{}
 | 
			
		||||
	tags := []Tag{}
 | 
			
		||||
	size := int64(0)
 | 
			
		||||
 | 
			
		||||
	for n, id := range repoTags {
 | 
			
		||||
		l, t, s, err := client.loadLayer(n, id)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Warnf("error loading layer: id=%s", id)
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		layers = append(layers, l...)
 | 
			
		||||
		tags = append(tags, t...)
 | 
			
		||||
		size += s
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	repository.Tags = tags
 | 
			
		||||
	repository.Layers = layers
 | 
			
		||||
	repository.Size = int64(size) / int64(len(tags))
 | 
			
		||||
 | 
			
		||||
	return repository, nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,47 +0,0 @@
 | 
			
		|||
package v1
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/engine-api/types"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type (
 | 
			
		||||
	Tag struct {
 | 
			
		||||
		ID   string
 | 
			
		||||
		Name string
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ContainerConfig struct {
 | 
			
		||||
		types.ContainerJSON
 | 
			
		||||
		Cmd []string `json:"Cmd,omitempty"`
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Layer struct {
 | 
			
		||||
		ID              string           `json:"id,omitempty"`
 | 
			
		||||
		Parent          string           `json:"parent,omitempty"`
 | 
			
		||||
		Created         *time.Time       `json:"created,omitempty"`
 | 
			
		||||
		Container       string           `json:"container,omitempty"`
 | 
			
		||||
		ContainerConfig *ContainerConfig `json:"container_config,omitempty"`
 | 
			
		||||
		DockerVersion   string           `json:"docker_version,omitempty"`
 | 
			
		||||
		Author          string           `json:"author,omitempty"`
 | 
			
		||||
		Architecture    string           `json:"architecture,omitempty"`
 | 
			
		||||
		OS              string           `json:"os,omitempty"`
 | 
			
		||||
		Size            int64            `json:"size,omitempty"`
 | 
			
		||||
		Ancestry        []string         `json:"ancestry,omitempty"`
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Repository struct {
 | 
			
		||||
		Description string  `json:"description,omitempty"`
 | 
			
		||||
		Name        string  `json:"name,omitempty"`
 | 
			
		||||
		Namespace   string  `json:"namespace,omitempty"`
 | 
			
		||||
		Repository  string  `json:"repository,omitempty"`
 | 
			
		||||
		Tags        []Tag   `json:"tags,omitempty"`
 | 
			
		||||
		Layers      []Layer `json:"layers,omitempty"`
 | 
			
		||||
		Size        int64   `json:"size,omitempty"`
 | 
			
		||||
		// these are only for the official index
 | 
			
		||||
		Trusted   bool `json:"is_trusted,omitempty"`
 | 
			
		||||
		Official  bool `json:"is_official,omitempty"`
 | 
			
		||||
		StarCount int  `json:"star_count,omitempty"`
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -1,10 +0,0 @@
 | 
			
		|||
package v1
 | 
			
		||||
 | 
			
		||||
type (
 | 
			
		||||
	SearchResult struct {
 | 
			
		||||
		NumberOfResults int           `json:"num_results,omitempty"`
 | 
			
		||||
		NumberOfPages   int           `json:"num_pages,omitempty"`
 | 
			
		||||
		Query           string        `json:"query,omitempty"`
 | 
			
		||||
		Results         []*Repository `json:"results,omitempty"`
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -1,149 +0,0 @@
 | 
			
		|||
package v2
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"crypto/tls"
 | 
			
		||||
	"crypto/x509"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	log "github.com/Sirupsen/logrus"
 | 
			
		||||
	"github.com/docker/orca"
 | 
			
		||||
	"github.com/docker/orca/auth"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	ErrNotFound        = errors.New("Not found")
 | 
			
		||||
	defaultHTTPTimeout = 30 * time.Second
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type (
 | 
			
		||||
	AuthToken struct {
 | 
			
		||||
		Token string `json:"token"`
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	V2Registry struct {
 | 
			
		||||
		orca.RegistryConfig
 | 
			
		||||
		client *orca.RegistryClient
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func NewRegistry(reg *orca.RegistryConfig, swarmTLSConfig *tls.Config) (orca.Registry, error) {
 | 
			
		||||
	// sanity check the registry settings
 | 
			
		||||
	u, err := url.Parse(reg.URL)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("The provided Docker Trusted Registry URL was malformed and could not be parsed")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Create a new TLS config for the registry, based on swarm's
 | 
			
		||||
	// This will allow us not to mess with the Swarm RootCAs
 | 
			
		||||
	tlsConfig := *swarmTLSConfig
 | 
			
		||||
	tlsConfig.InsecureSkipVerify = reg.Insecure
 | 
			
		||||
	if reg.CACert != "" {
 | 
			
		||||
		// If the user specified a CA, create a new RootCA pool containing only that CA cert.
 | 
			
		||||
		log.Debugf("cert: %s", reg.CACert)
 | 
			
		||||
		certPool := x509.NewCertPool()
 | 
			
		||||
		certPool.AppendCertsFromPEM([]byte(reg.CACert))
 | 
			
		||||
		tlsConfig.RootCAs = certPool
 | 
			
		||||
		log.Debug("Connecting to Registry with user-provided CA")
 | 
			
		||||
	} else {
 | 
			
		||||
		// If the user did not specify a CA, fall back to the system's Root CAs
 | 
			
		||||
		tlsConfig.RootCAs = nil
 | 
			
		||||
		log.Debug("Connecting to Registry with system Root CAs")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	httpClient := &http.Client{
 | 
			
		||||
		Transport: &http.Transport{TLSClientConfig: &tlsConfig},
 | 
			
		||||
		Timeout:   defaultHTTPTimeout,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	rClient := &orca.RegistryClient{
 | 
			
		||||
		URL:        u,
 | 
			
		||||
		HttpClient: httpClient,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &V2Registry{
 | 
			
		||||
		RegistryConfig: *reg,
 | 
			
		||||
		client:         rClient,
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *V2Registry) doRequest(method string, path string, body []byte, headers map[string]string, username string) ([]byte, error) {
 | 
			
		||||
	b := bytes.NewBuffer(body)
 | 
			
		||||
 | 
			
		||||
	req, err := http.NewRequest(method, path, b)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Errorf("couldn't create request: %s", err)
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// The DTR Auth server will validate the UCP client cert and will grant access to whatever
 | 
			
		||||
	// username is passed to it.
 | 
			
		||||
	// However, DTR 1.4.3 rejects empty password strings under LDAP, in order to disallow anonymous users.
 | 
			
		||||
	req.SetBasicAuth(username, "really?")
 | 
			
		||||
 | 
			
		||||
	if headers != nil {
 | 
			
		||||
		for header, value := range headers {
 | 
			
		||||
			req.Header.Add(header, value)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	resp, err := r.client.HttpClient.Do(req)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		if err == http.ErrHandlerTimeout {
 | 
			
		||||
			log.Error("Login timed out to Docker Trusted Registry")
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		log.Errorf("There was an error while authenticating: %s", err)
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	defer resp.Body.Close()
 | 
			
		||||
 | 
			
		||||
	if resp.StatusCode == 401 {
 | 
			
		||||
		// Unauthorized
 | 
			
		||||
		log.Warnf("Unauthorized")
 | 
			
		||||
		return nil, auth.ErrUnauthorized
 | 
			
		||||
	} else if resp.StatusCode >= 400 {
 | 
			
		||||
		log.Errorf("Docker Trusted Registry returned an unexpected status code while authenticating: %s", resp.Status)
 | 
			
		||||
		return nil, auth.ErrUnknown
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	rBody, err := ioutil.ReadAll(resp.Body)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Errorf("couldn't read body: %s", err)
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return rBody, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *V2Registry) GetAuthToken(username, accessType, hostname, reponame string) (string, error) {
 | 
			
		||||
	uri := fmt.Sprintf("%s/auth/token?scope=repository:%s:%s&service=%s", r.RegistryConfig.URL, reponame, accessType, hostname)
 | 
			
		||||
 | 
			
		||||
	log.Debugf("contacting DTR for auth token: %s", uri)
 | 
			
		||||
 | 
			
		||||
	data, err := r.doRequest("GET", uri, nil, nil, username)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var token AuthToken
 | 
			
		||||
	if err := json.Unmarshal(data, &token); err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return token.Token, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *V2Registry) GetConfig() *orca.RegistryConfig {
 | 
			
		||||
	return &r.RegistryConfig
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *V2Registry) GetTransport() http.RoundTripper {
 | 
			
		||||
	return r.client.HttpClient.Transport
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue