Add a `CredentialsForHost` method to disco.Disco
By adding this method you now only have to pass a `*disco.Disco` object around in order to do discovery and use any configured credentials for the discovered hosts. Of course you can also still pass around both a `*disco.Disco` and a `auth.CredentialsSource` object if there is a need or a reason for that!
This commit is contained in:
parent
495d1ea350
commit
179b32d426
|
@ -117,7 +117,7 @@ func testModule(t *testing.T, name string) *module.Tree {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatalf("err: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
s := module.NewStorage(tempDir(t), nil, nil)
|
s := module.NewStorage(tempDir(t), nil)
|
||||||
s.Mode = module.GetModeGet
|
s.Mode = module.GetModeGet
|
||||||
if err := mod.Load(s); err != nil {
|
if err := mod.Load(s); err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatalf("err: %s", err)
|
||||||
|
|
|
@ -129,7 +129,7 @@ func (c *InitCommand) Run(args []string) int {
|
||||||
)))
|
)))
|
||||||
header = true
|
header = true
|
||||||
|
|
||||||
s := module.NewStorage("", c.Services, c.Credentials)
|
s := module.NewStorage("", c.Services)
|
||||||
if err := s.GetModule(path, src); err != nil {
|
if err := s.GetModule(path, src); err != nil {
|
||||||
c.Ui.Error(fmt.Sprintf("Error copying source module: %s", err))
|
c.Ui.Error(fmt.Sprintf("Error copying source module: %s", err))
|
||||||
return 1
|
return 1
|
||||||
|
|
|
@ -25,7 +25,6 @@ import (
|
||||||
"github.com/hashicorp/terraform/helper/experiment"
|
"github.com/hashicorp/terraform/helper/experiment"
|
||||||
"github.com/hashicorp/terraform/helper/variables"
|
"github.com/hashicorp/terraform/helper/variables"
|
||||||
"github.com/hashicorp/terraform/helper/wrappedstreams"
|
"github.com/hashicorp/terraform/helper/wrappedstreams"
|
||||||
"github.com/hashicorp/terraform/svchost/auth"
|
|
||||||
"github.com/hashicorp/terraform/svchost/disco"
|
"github.com/hashicorp/terraform/svchost/disco"
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"github.com/hashicorp/terraform/terraform"
|
||||||
"github.com/hashicorp/terraform/tfdiags"
|
"github.com/hashicorp/terraform/tfdiags"
|
||||||
|
@ -51,10 +50,6 @@ type Meta struct {
|
||||||
// "terraform-native' services running at a specific user-facing hostname.
|
// "terraform-native' services running at a specific user-facing hostname.
|
||||||
Services *disco.Disco
|
Services *disco.Disco
|
||||||
|
|
||||||
// Credentials provides access to credentials for "terraform-native"
|
|
||||||
// services, which are accessed by a service hostname.
|
|
||||||
Credentials auth.CredentialsSource
|
|
||||||
|
|
||||||
// RunningInAutomation indicates that commands are being run by an
|
// RunningInAutomation indicates that commands are being run by an
|
||||||
// automated system rather than directly at a command prompt.
|
// automated system rather than directly at a command prompt.
|
||||||
//
|
//
|
||||||
|
@ -410,7 +405,7 @@ func (m *Meta) flagSet(n string) *flag.FlagSet {
|
||||||
// moduleStorage returns the module.Storage implementation used to store
|
// moduleStorage returns the module.Storage implementation used to store
|
||||||
// modules for commands.
|
// modules for commands.
|
||||||
func (m *Meta) moduleStorage(root string, mode module.GetMode) *module.Storage {
|
func (m *Meta) moduleStorage(root string, mode module.GetMode) *module.Storage {
|
||||||
s := module.NewStorage(filepath.Join(root, "modules"), m.Services, m.Credentials)
|
s := module.NewStorage(filepath.Join(root, "modules"), m.Services)
|
||||||
s.Ui = m.Ui
|
s.Ui = m.Ui
|
||||||
s.Mode = mode
|
s.Mode = mode
|
||||||
return s
|
return s
|
||||||
|
|
|
@ -30,15 +30,12 @@ const (
|
||||||
OutputPrefix = "o:"
|
OutputPrefix = "o:"
|
||||||
)
|
)
|
||||||
|
|
||||||
func initCommands(config *Config) {
|
func initCommands(config *Config, services *disco.Disco) {
|
||||||
var inAutomation bool
|
var inAutomation bool
|
||||||
if v := os.Getenv(runningInAutomationEnvName); v != "" {
|
if v := os.Getenv(runningInAutomationEnvName); v != "" {
|
||||||
inAutomation = true
|
inAutomation = true
|
||||||
}
|
}
|
||||||
|
|
||||||
credsSrc := credentialsSource(config)
|
|
||||||
services := disco.NewDisco()
|
|
||||||
services.SetCredentialsSource(credsSrc)
|
|
||||||
for userHost, hostConfig := range config.Hosts {
|
for userHost, hostConfig := range config.Hosts {
|
||||||
host, err := svchost.ForComparison(userHost)
|
host, err := svchost.ForComparison(userHost)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -57,8 +54,7 @@ func initCommands(config *Config) {
|
||||||
PluginOverrides: &PluginOverrides,
|
PluginOverrides: &PluginOverrides,
|
||||||
Ui: Ui,
|
Ui: Ui,
|
||||||
|
|
||||||
Services: services,
|
Services: services,
|
||||||
Credentials: credsSrc,
|
|
||||||
|
|
||||||
RunningInAutomation: inAutomation,
|
RunningInAutomation: inAutomation,
|
||||||
PluginCacheDir: config.PluginCacheDir,
|
PluginCacheDir: config.PluginCacheDir,
|
||||||
|
|
|
@ -44,5 +44,5 @@ func testConfig(t *testing.T, n string) *config.Config {
|
||||||
|
|
||||||
func testStorage(t *testing.T, d *disco.Disco) *Storage {
|
func testStorage(t *testing.T, d *disco.Disco) *Storage {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
return NewStorage(tempDir(t), d, nil)
|
return NewStorage(tempDir(t), d)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ import (
|
||||||
getter "github.com/hashicorp/go-getter"
|
getter "github.com/hashicorp/go-getter"
|
||||||
"github.com/hashicorp/terraform/registry"
|
"github.com/hashicorp/terraform/registry"
|
||||||
"github.com/hashicorp/terraform/registry/regsrc"
|
"github.com/hashicorp/terraform/registry/regsrc"
|
||||||
"github.com/hashicorp/terraform/svchost/auth"
|
|
||||||
"github.com/hashicorp/terraform/svchost/disco"
|
"github.com/hashicorp/terraform/svchost/disco"
|
||||||
"github.com/mitchellh/cli"
|
"github.com/mitchellh/cli"
|
||||||
)
|
)
|
||||||
|
@ -64,14 +63,10 @@ type Storage struct {
|
||||||
// StorageDir is the full path to the directory where all modules will be
|
// StorageDir is the full path to the directory where all modules will be
|
||||||
// stored.
|
// stored.
|
||||||
StorageDir string
|
StorageDir string
|
||||||
// Services is a required *disco.Disco, which may have services and
|
|
||||||
// credentials pre-loaded.
|
|
||||||
Services *disco.Disco
|
|
||||||
// Creds optionally provides credentials for communicating with service
|
|
||||||
// providers.
|
|
||||||
Creds auth.CredentialsSource
|
|
||||||
// Ui is an optional cli.Ui for user output
|
// Ui is an optional cli.Ui for user output
|
||||||
Ui cli.Ui
|
Ui cli.Ui
|
||||||
|
|
||||||
// Mode is the GetMode that will be used for various operations.
|
// Mode is the GetMode that will be used for various operations.
|
||||||
Mode GetMode
|
Mode GetMode
|
||||||
|
|
||||||
|
@ -79,8 +74,8 @@ type Storage struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewStorage returns a new initialized Storage object.
|
// NewStorage returns a new initialized Storage object.
|
||||||
func NewStorage(dir string, services *disco.Disco, creds auth.CredentialsSource) *Storage {
|
func NewStorage(dir string, services *disco.Disco) *Storage {
|
||||||
regClient := registry.NewClient(services, creds, nil)
|
regClient := registry.NewClient(services, nil)
|
||||||
|
|
||||||
return &Storage{
|
return &Storage{
|
||||||
StorageDir: dir,
|
StorageDir: dir,
|
||||||
|
|
|
@ -22,7 +22,7 @@ func TestGetModule(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
defer os.RemoveAll(td)
|
defer os.RemoveAll(td)
|
||||||
storage := NewStorage(td, disco, nil)
|
storage := NewStorage(td, disco)
|
||||||
|
|
||||||
// this module exists in a test fixture, and is known by the test.Registry
|
// this module exists in a test fixture, and is known by the test.Registry
|
||||||
// relative to our cwd.
|
// relative to our cwd.
|
||||||
|
@ -139,7 +139,7 @@ func TestAccRegistryDiscover(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
s := NewStorage("/tmp", nil, nil)
|
s := NewStorage("/tmp", nil)
|
||||||
loc, err := s.registry.Location(module, "")
|
loc, err := s.registry.Location(module, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/configs"
|
"github.com/hashicorp/terraform/configs"
|
||||||
"github.com/hashicorp/terraform/registry"
|
"github.com/hashicorp/terraform/registry"
|
||||||
"github.com/hashicorp/terraform/svchost/auth"
|
|
||||||
"github.com/hashicorp/terraform/svchost/disco"
|
"github.com/hashicorp/terraform/svchost/disco"
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
)
|
)
|
||||||
|
@ -39,10 +38,6 @@ type Config struct {
|
||||||
// not supported, which should be true only in specialized circumstances
|
// not supported, which should be true only in specialized circumstances
|
||||||
// such as in tests.
|
// such as in tests.
|
||||||
Services *disco.Disco
|
Services *disco.Disco
|
||||||
|
|
||||||
// Creds is a credentials store for communicating with remote module
|
|
||||||
// registry endpoints. If this is nil then no credentials will be used.
|
|
||||||
Creds auth.CredentialsSource
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewLoader creates and returns a loader that reads configuration from the
|
// NewLoader creates and returns a loader that reads configuration from the
|
||||||
|
@ -54,7 +49,7 @@ type Config struct {
|
||||||
func NewLoader(config *Config) (*Loader, error) {
|
func NewLoader(config *Config) (*Loader, error) {
|
||||||
fs := afero.NewOsFs()
|
fs := afero.NewOsFs()
|
||||||
parser := configs.NewParser(fs)
|
parser := configs.NewParser(fs)
|
||||||
reg := registry.NewClient(config.Services, config.Creds, nil)
|
reg := registry.NewClient(config.Services, nil)
|
||||||
|
|
||||||
ret := &Loader{
|
ret := &Loader{
|
||||||
parser: parser,
|
parser: parser,
|
||||||
|
@ -63,7 +58,6 @@ func NewLoader(config *Config) (*Loader, error) {
|
||||||
CanInstall: true,
|
CanInstall: true,
|
||||||
Dir: config.ModulesDir,
|
Dir: config.ModulesDir,
|
||||||
Services: config.Services,
|
Services: config.Services,
|
||||||
Creds: config.Creds,
|
|
||||||
Registry: reg,
|
Registry: reg,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package configload
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/terraform/registry"
|
"github.com/hashicorp/terraform/registry"
|
||||||
"github.com/hashicorp/terraform/svchost/auth"
|
|
||||||
"github.com/hashicorp/terraform/svchost/disco"
|
"github.com/hashicorp/terraform/svchost/disco"
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
)
|
)
|
||||||
|
@ -25,9 +24,6 @@ type moduleMgr struct {
|
||||||
// cached discovery information.
|
// cached discovery information.
|
||||||
Services *disco.Disco
|
Services *disco.Disco
|
||||||
|
|
||||||
// Creds provides optional credentials for communicating with service hosts.
|
|
||||||
Creds auth.CredentialsSource
|
|
||||||
|
|
||||||
// Registry is a client for the module registry protocol, which is used
|
// Registry is a client for the module registry protocol, which is used
|
||||||
// when a module is requested from a registry source.
|
// when a module is requested from a registry source.
|
||||||
Registry *registry.Client
|
Registry *registry.Client
|
||||||
|
|
5
main.go
5
main.go
|
@ -16,6 +16,7 @@ import (
|
||||||
"github.com/hashicorp/go-plugin"
|
"github.com/hashicorp/go-plugin"
|
||||||
"github.com/hashicorp/terraform/command/format"
|
"github.com/hashicorp/terraform/command/format"
|
||||||
"github.com/hashicorp/terraform/helper/logging"
|
"github.com/hashicorp/terraform/helper/logging"
|
||||||
|
"github.com/hashicorp/terraform/svchost/disco"
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"github.com/hashicorp/terraform/terraform"
|
||||||
"github.com/mattn/go-colorable"
|
"github.com/mattn/go-colorable"
|
||||||
"github.com/mattn/go-shellwords"
|
"github.com/mattn/go-shellwords"
|
||||||
|
@ -144,7 +145,9 @@ func wrappedMain() int {
|
||||||
|
|
||||||
// In tests, Commands may already be set to provide mock commands
|
// In tests, Commands may already be set to provide mock commands
|
||||||
if Commands == nil {
|
if Commands == nil {
|
||||||
initCommands(config)
|
credsSrc := credentialsSource(config)
|
||||||
|
services := disco.NewWithCredentialsSource(credsSrc)
|
||||||
|
initCommands(config, services)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run checkpoint
|
// Run checkpoint
|
||||||
|
|
|
@ -15,7 +15,6 @@ import (
|
||||||
"github.com/hashicorp/terraform/registry/regsrc"
|
"github.com/hashicorp/terraform/registry/regsrc"
|
||||||
"github.com/hashicorp/terraform/registry/response"
|
"github.com/hashicorp/terraform/registry/response"
|
||||||
"github.com/hashicorp/terraform/svchost"
|
"github.com/hashicorp/terraform/svchost"
|
||||||
"github.com/hashicorp/terraform/svchost/auth"
|
|
||||||
"github.com/hashicorp/terraform/svchost/disco"
|
"github.com/hashicorp/terraform/svchost/disco"
|
||||||
"github.com/hashicorp/terraform/version"
|
"github.com/hashicorp/terraform/version"
|
||||||
)
|
)
|
||||||
|
@ -37,20 +36,14 @@ type Client struct {
|
||||||
// services is a required *disco.Disco, which may have services and
|
// services is a required *disco.Disco, which may have services and
|
||||||
// credentials pre-loaded.
|
// credentials pre-loaded.
|
||||||
services *disco.Disco
|
services *disco.Disco
|
||||||
|
|
||||||
// Creds optionally provides credentials for communicating with service
|
|
||||||
// providers.
|
|
||||||
creds auth.CredentialsSource
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewClient returns a new initialized registry client.
|
// NewClient returns a new initialized registry client.
|
||||||
func NewClient(services *disco.Disco, creds auth.CredentialsSource, client *http.Client) *Client {
|
func NewClient(services *disco.Disco, client *http.Client) *Client {
|
||||||
if services == nil {
|
if services == nil {
|
||||||
services = disco.NewDisco()
|
services = disco.New()
|
||||||
}
|
}
|
||||||
|
|
||||||
services.SetCredentialsSource(creds)
|
|
||||||
|
|
||||||
if client == nil {
|
if client == nil {
|
||||||
client = httpclient.New()
|
client = httpclient.New()
|
||||||
client.Timeout = requestTimeout
|
client.Timeout = requestTimeout
|
||||||
|
@ -61,7 +54,6 @@ func NewClient(services *disco.Disco, creds auth.CredentialsSource, client *http
|
||||||
return &Client{
|
return &Client{
|
||||||
client: client,
|
client: client,
|
||||||
services: services,
|
services: services,
|
||||||
creds: creds,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,11 +130,7 @@ func (c *Client) Versions(module *regsrc.Module) (*response.ModuleVersions, erro
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) addRequestCreds(host svchost.Hostname, req *http.Request) {
|
func (c *Client) addRequestCreds(host svchost.Hostname, req *http.Request) {
|
||||||
if c.creds == nil {
|
creds, err := c.services.CredentialsForHost(host)
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
creds, err := c.creds.ForHost(host)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[WARN] Failed to get credentials for %s: %s (ignoring)", host, err)
|
log.Printf("[WARN] Failed to get credentials for %s: %s (ignoring)", host, err)
|
||||||
return
|
return
|
||||||
|
|
|
@ -15,7 +15,7 @@ func TestLookupModuleVersions(t *testing.T) {
|
||||||
server := test.Registry()
|
server := test.Registry()
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
client := NewClient(test.Disco(server), nil, nil)
|
client := NewClient(test.Disco(server), nil)
|
||||||
|
|
||||||
// test with and without a hostname
|
// test with and without a hostname
|
||||||
for _, src := range []string{
|
for _, src := range []string{
|
||||||
|
@ -59,7 +59,7 @@ func TestInvalidRegistry(t *testing.T) {
|
||||||
server := test.Registry()
|
server := test.Registry()
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
client := NewClient(test.Disco(server), nil, nil)
|
client := NewClient(test.Disco(server), nil)
|
||||||
|
|
||||||
src := "non-existent.localhost.localdomain/test-versions/name/provider"
|
src := "non-existent.localhost.localdomain/test-versions/name/provider"
|
||||||
modsrc, err := regsrc.ParseModuleSource(src)
|
modsrc, err := regsrc.ParseModuleSource(src)
|
||||||
|
@ -76,7 +76,7 @@ func TestRegistryAuth(t *testing.T) {
|
||||||
server := test.Registry()
|
server := test.Registry()
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
client := NewClient(test.Disco(server), nil, nil)
|
client := NewClient(test.Disco(server), nil)
|
||||||
|
|
||||||
src := "private/name/provider"
|
src := "private/name/provider"
|
||||||
mod, err := regsrc.ParseModuleSource(src)
|
mod, err := regsrc.ParseModuleSource(src)
|
||||||
|
@ -84,6 +84,18 @@ func TestRegistryAuth(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_, err = client.Versions(mod)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
_, err = client.Location(mod, "1.0.0")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also test without a credentials source
|
||||||
|
client.services.SetCredentialsSource(nil)
|
||||||
|
|
||||||
// both should fail without auth
|
// both should fail without auth
|
||||||
_, err = client.Versions(mod)
|
_, err = client.Versions(mod)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -93,24 +105,13 @@ func TestRegistryAuth(t *testing.T) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("expected error")
|
t.Fatal("expected error")
|
||||||
}
|
}
|
||||||
|
|
||||||
client = NewClient(test.Disco(server), test.Credentials, nil)
|
|
||||||
|
|
||||||
_, err = client.Versions(mod)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
_, err = client.Location(mod, "1.0.0")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLookupModuleLocationRelative(t *testing.T) {
|
func TestLookupModuleLocationRelative(t *testing.T) {
|
||||||
server := test.Registry()
|
server := test.Registry()
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
client := NewClient(test.Disco(server), nil, nil)
|
client := NewClient(test.Disco(server), nil)
|
||||||
|
|
||||||
src := "relative/foo/bar"
|
src := "relative/foo/bar"
|
||||||
mod, err := regsrc.ParseModuleSource(src)
|
mod, err := regsrc.ParseModuleSource(src)
|
||||||
|
@ -133,7 +134,7 @@ func TestAccLookupModuleVersions(t *testing.T) {
|
||||||
if os.Getenv("TF_ACC") == "" {
|
if os.Getenv("TF_ACC") == "" {
|
||||||
t.Skip()
|
t.Skip()
|
||||||
}
|
}
|
||||||
regDisco := disco.NewDisco()
|
regDisco := disco.New()
|
||||||
|
|
||||||
// test with and without a hostname
|
// test with and without a hostname
|
||||||
for _, src := range []string{
|
for _, src := range []string{
|
||||||
|
@ -145,7 +146,7 @@ func TestAccLookupModuleVersions(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
s := NewClient(regDisco, nil, nil)
|
s := NewClient(regDisco, nil)
|
||||||
resp, err := s.Versions(modsrc)
|
resp, err := s.Versions(modsrc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
@ -179,7 +180,7 @@ func TestLookupLookupModuleError(t *testing.T) {
|
||||||
server := test.Registry()
|
server := test.Registry()
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
client := NewClient(test.Disco(server), nil, nil)
|
client := NewClient(test.Disco(server), nil)
|
||||||
|
|
||||||
// this should not be found in teh registry
|
// this should not be found in teh registry
|
||||||
src := "bad/local/path"
|
src := "bad/local/path"
|
||||||
|
|
|
@ -27,7 +27,7 @@ func Disco(s *httptest.Server) *disco.Disco {
|
||||||
// TODO: add specific tests to enumerate both possibilities.
|
// TODO: add specific tests to enumerate both possibilities.
|
||||||
"modules.v1": fmt.Sprintf("%s/v1/modules", s.URL),
|
"modules.v1": fmt.Sprintf("%s/v1/modules", s.URL),
|
||||||
}
|
}
|
||||||
d := disco.NewDisco()
|
d := disco.NewWithCredentialsSource(credsSrc)
|
||||||
|
|
||||||
d.ForceHostServices(svchost.Hostname("registry.terraform.io"), services)
|
d.ForceHostServices(svchost.Hostname("registry.terraform.io"), services)
|
||||||
d.ForceHostServices(svchost.Hostname("localhost"), services)
|
d.ForceHostServices(svchost.Hostname("localhost"), services)
|
||||||
|
@ -48,8 +48,8 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
regHost = svchost.Hostname(regsrc.PublicRegistryHost.Normalized())
|
regHost = svchost.Hostname(regsrc.PublicRegistryHost.Normalized())
|
||||||
Credentials = auth.StaticCredentialsSource(map[svchost.Hostname]map[string]interface{}{
|
credsSrc = auth.StaticCredentialsSource(map[svchost.Hostname]map[string]interface{}{
|
||||||
regHost: {"token": testCred},
|
regHost: {"token": testCred},
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
|
@ -42,6 +42,9 @@ type HostCredentials interface {
|
||||||
// receiving credentials. The usual behavior of this method is to
|
// receiving credentials. The usual behavior of this method is to
|
||||||
// add some sort of Authorization header to the request.
|
// add some sort of Authorization header to the request.
|
||||||
PrepareRequest(req *http.Request)
|
PrepareRequest(req *http.Request)
|
||||||
|
|
||||||
|
// Token returns the authentication token.
|
||||||
|
Token() string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForHost iterates over the contained CredentialsSource objects and
|
// ForHost iterates over the contained CredentialsSource objects and
|
||||||
|
|
|
@ -18,3 +18,8 @@ func (tc HostCredentialsToken) PrepareRequest(req *http.Request) {
|
||||||
}
|
}
|
||||||
req.Header.Set("Authorization", "Bearer "+string(tc))
|
req.Header.Set("Authorization", "Bearer "+string(tc))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Token returns the authentication token.
|
||||||
|
func (tc HostCredentialsToken) Token() string {
|
||||||
|
return string(tc)
|
||||||
|
}
|
||||||
|
|
|
@ -42,9 +42,15 @@ type Disco struct {
|
||||||
Transport http.RoundTripper
|
Transport http.RoundTripper
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDisco returns a new initialized Disco object.
|
// New returns a new initialized discovery object.
|
||||||
func NewDisco() *Disco {
|
func New() *Disco {
|
||||||
return &Disco{}
|
return NewWithCredentialsSource(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewWithCredentialsSource returns a new discovery object initialized with
|
||||||
|
// the given credentials source.
|
||||||
|
func NewWithCredentialsSource(credsSrc auth.CredentialsSource) *Disco {
|
||||||
|
return &Disco{credsSrc: credsSrc}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetCredentialsSource provides a credentials source that will be used to
|
// SetCredentialsSource provides a credentials source that will be used to
|
||||||
|
@ -56,6 +62,15 @@ func (d *Disco) SetCredentialsSource(src auth.CredentialsSource) {
|
||||||
d.credsSrc = src
|
d.credsSrc = src
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CredentialsForHost returns a non-nil HostCredentials if the embedded source has
|
||||||
|
// credentials available for the host, and a nil HostCredentials if it does not.
|
||||||
|
func (d *Disco) CredentialsForHost(host svchost.Hostname) (auth.HostCredentials, error) {
|
||||||
|
if d.credsSrc == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return d.credsSrc.ForHost(host)
|
||||||
|
}
|
||||||
|
|
||||||
// ForceHostServices provides a pre-defined set of services for a given
|
// ForceHostServices provides a pre-defined set of services for a given
|
||||||
// host, which prevents the receiver from attempting network-based discovery
|
// host, which prevents the receiver from attempting network-based discovery
|
||||||
// for the given host. Instead, the given services map will be returned
|
// for the given host. Instead, the given services map will be returned
|
||||||
|
@ -145,15 +160,10 @@ func (d *Disco) discover(host svchost.Hostname) Host {
|
||||||
URL: discoURL,
|
URL: discoURL,
|
||||||
}
|
}
|
||||||
|
|
||||||
if d.credsSrc != nil {
|
if creds, err := d.CredentialsForHost(host); err != nil {
|
||||||
creds, err := d.credsSrc.ForHost(host)
|
log.Printf("[WARN] Failed to get credentials for %s: %s (ignoring)", host, err)
|
||||||
if err == nil {
|
} else if creds != nil {
|
||||||
if creds != nil {
|
creds.PrepareRequest(req) // alters req to include credentials
|
||||||
creds.PrepareRequest(req) // alters req to include credentials
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.Printf("[WARN] Failed to get credentials for %s: %s (ignoring)", host, err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("[DEBUG] Service discovery for %s at %s", host, discoURL)
|
log.Printf("[DEBUG] Service discovery for %s at %s", host, discoURL)
|
||||||
|
|
|
@ -45,7 +45,7 @@ func TestDiscover(t *testing.T) {
|
||||||
t.Fatalf("test server hostname is invalid: %s", err)
|
t.Fatalf("test server hostname is invalid: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d := NewDisco()
|
d := New()
|
||||||
discovered := d.Discover(host)
|
discovered := d.Discover(host)
|
||||||
gotURL := discovered.ServiceURL("thingy.v1")
|
gotURL := discovered.ServiceURL("thingy.v1")
|
||||||
if gotURL == nil {
|
if gotURL == nil {
|
||||||
|
@ -80,7 +80,7 @@ func TestDiscover(t *testing.T) {
|
||||||
t.Fatalf("test server hostname is invalid: %s", err)
|
t.Fatalf("test server hostname is invalid: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d := NewDisco()
|
d := New()
|
||||||
discovered := d.Discover(host)
|
discovered := d.Discover(host)
|
||||||
gotURL := discovered.ServiceURL("wotsit.v2")
|
gotURL := discovered.ServiceURL("wotsit.v2")
|
||||||
if gotURL == nil {
|
if gotURL == nil {
|
||||||
|
@ -107,7 +107,7 @@ func TestDiscover(t *testing.T) {
|
||||||
t.Fatalf("test server hostname is invalid: %s", err)
|
t.Fatalf("test server hostname is invalid: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d := NewDisco()
|
d := New()
|
||||||
d.SetCredentialsSource(auth.StaticCredentialsSource(map[svchost.Hostname]map[string]interface{}{
|
d.SetCredentialsSource(auth.StaticCredentialsSource(map[svchost.Hostname]map[string]interface{}{
|
||||||
host: map[string]interface{}{
|
host: map[string]interface{}{
|
||||||
"token": "abc123",
|
"token": "abc123",
|
||||||
|
@ -124,7 +124,7 @@ func TestDiscover(t *testing.T) {
|
||||||
"wotsit.v2": "/foo",
|
"wotsit.v2": "/foo",
|
||||||
}
|
}
|
||||||
|
|
||||||
d := NewDisco()
|
d := New()
|
||||||
d.ForceHostServices(svchost.Hostname("example.com"), forced)
|
d.ForceHostServices(svchost.Hostname("example.com"), forced)
|
||||||
|
|
||||||
givenHost := "example.com"
|
givenHost := "example.com"
|
||||||
|
@ -167,7 +167,7 @@ func TestDiscover(t *testing.T) {
|
||||||
t.Fatalf("test server hostname is invalid: %s", err)
|
t.Fatalf("test server hostname is invalid: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d := NewDisco()
|
d := New()
|
||||||
discovered := d.Discover(host)
|
discovered := d.Discover(host)
|
||||||
|
|
||||||
// result should be empty, which we can verify only by reaching into
|
// result should be empty, which we can verify only by reaching into
|
||||||
|
@ -190,7 +190,7 @@ func TestDiscover(t *testing.T) {
|
||||||
t.Fatalf("test server hostname is invalid: %s", err)
|
t.Fatalf("test server hostname is invalid: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d := NewDisco()
|
d := New()
|
||||||
discovered := d.Discover(host)
|
discovered := d.Discover(host)
|
||||||
|
|
||||||
// result should be empty, which we can verify only by reaching into
|
// result should be empty, which we can verify only by reaching into
|
||||||
|
@ -217,7 +217,7 @@ func TestDiscover(t *testing.T) {
|
||||||
t.Fatalf("test server hostname is invalid: %s", err)
|
t.Fatalf("test server hostname is invalid: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d := NewDisco()
|
d := New()
|
||||||
discovered := d.Discover(host)
|
discovered := d.Discover(host)
|
||||||
|
|
||||||
if discovered.services == nil {
|
if discovered.services == nil {
|
||||||
|
@ -236,7 +236,7 @@ func TestDiscover(t *testing.T) {
|
||||||
t.Fatalf("test server hostname is invalid: %s", err)
|
t.Fatalf("test server hostname is invalid: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d := NewDisco()
|
d := New()
|
||||||
discovered := d.Discover(host)
|
discovered := d.Discover(host)
|
||||||
|
|
||||||
// result should be empty, which we can verify only by reaching into
|
// result should be empty, which we can verify only by reaching into
|
||||||
|
@ -267,7 +267,7 @@ func TestDiscover(t *testing.T) {
|
||||||
t.Fatalf("test server hostname is invalid: %s", err)
|
t.Fatalf("test server hostname is invalid: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d := NewDisco()
|
d := New()
|
||||||
discovered := d.Discover(host)
|
discovered := d.Discover(host)
|
||||||
|
|
||||||
gotURL := discovered.ServiceURL("thingy.v1")
|
gotURL := discovered.ServiceURL("thingy.v1")
|
||||||
|
|
Loading…
Reference in New Issue