github.com/rogpeppe/juju@v0.0.0-20140613142852-6337964b789e/environs/tools/urls.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package tools
     5  
     6  import (
     7  	"fmt"
     8  	"net/url"
     9  	"strings"
    10  
    11  	"github.com/juju/utils"
    12  
    13  	"github.com/juju/juju/environs"
    14  	"github.com/juju/juju/environs/simplestreams"
    15  	"github.com/juju/juju/environs/storage"
    16  )
    17  
    18  // SupportsCustomSources represents an environment that
    19  // can host tools metadata at provider specific sources.
    20  type SupportsCustomSources interface {
    21  	GetToolsSources() ([]simplestreams.DataSource, error)
    22  }
    23  
    24  // GetMetadataSources returns the sources to use when looking for
    25  // simplestreams tools metadata. If env implements SupportsCustomSurces,
    26  // the sources returned from that method will also be considered.
    27  // The sources are configured to not use retries.
    28  func GetMetadataSources(env environs.ConfigGetter) ([]simplestreams.DataSource, error) {
    29  	return GetMetadataSourcesWithRetries(env, false)
    30  }
    31  
    32  // GetMetadataSourcesWithRetries returns the sources to use when looking for
    33  // simplestreams tools metadata. If env implements SupportsCustomSurces,
    34  // the sources returned from that method will also be considered.
    35  // The sources are configured to use retries according to the value of allowRetry.
    36  func GetMetadataSourcesWithRetries(env environs.ConfigGetter, allowRetry bool) ([]simplestreams.DataSource, error) {
    37  	var sources []simplestreams.DataSource
    38  	config := env.Config()
    39  	if userURL, ok := config.ToolsURL(); ok {
    40  		verify := utils.VerifySSLHostnames
    41  		if !config.SSLHostnameVerification() {
    42  			verify = utils.NoVerifySSLHostnames
    43  		}
    44  		sources = append(sources, simplestreams.NewURLDataSource("tools-metadata-url", userURL, verify))
    45  	}
    46  	if custom, ok := env.(SupportsCustomSources); ok {
    47  		customSources, err := custom.GetToolsSources()
    48  		if err != nil {
    49  			return nil, err
    50  		}
    51  		sources = append(sources, customSources...)
    52  	}
    53  
    54  	defaultURL, err := ToolsURL(DefaultBaseURL)
    55  	if err != nil {
    56  		return nil, err
    57  	}
    58  	if defaultURL != "" {
    59  		sources = append(sources,
    60  			simplestreams.NewURLDataSource("default simplestreams", defaultURL, utils.VerifySSLHostnames))
    61  	}
    62  	for _, source := range sources {
    63  		source.SetAllowRetry(allowRetry)
    64  	}
    65  	return sources, nil
    66  }
    67  
    68  // ToolsURL returns a valid tools URL constructed from source.
    69  // source may be a directory, or a URL like file://foo or http://foo.
    70  func ToolsURL(source string) (string, error) {
    71  	if source == "" {
    72  		return "", nil
    73  	}
    74  	// If source is a raw directory, we need to append the file:// prefix
    75  	// so it can be used as a URL.
    76  	defaultURL := source
    77  	u, err := url.Parse(source)
    78  	if err != nil {
    79  		return "", fmt.Errorf("invalid default tools URL %s: %v", defaultURL, err)
    80  	}
    81  	if u.Scheme == "" {
    82  		defaultURL = "file://" + defaultURL
    83  		if !strings.HasSuffix(defaultURL, "/"+storage.BaseToolsPath) {
    84  			defaultURL = fmt.Sprintf("%s/%s", defaultURL, storage.BaseToolsPath)
    85  		}
    86  	}
    87  	return defaultURL, nil
    88  }