datasource/vmware: introduce guestinfo.coreos.config.url
allow use of a URL instead of an inline document. Inline document takes precedence.
This commit is contained in:
parent
de38ac5c98
commit
ed512c1cac
@ -19,6 +19,7 @@ are supported by coreos-cloudinit:
|
|||||||
| `dns.server.<x>` | `IP address` |
|
| `dns.server.<x>` | `IP address` |
|
||||||
| `coreos.config.data` | `string` |
|
| `coreos.config.data` | `string` |
|
||||||
| `coreos.config.data.encoding` | `{"", "base64", "gzip+base64"}` |
|
| `coreos.config.data.encoding` | `{"", "base64", "gzip+base64"}` |
|
||||||
|
| `coreos.config.url` | `URL` |
|
||||||
|
|
||||||
Note: "n", "m", "l", and "x" are 0-indexed, incrementing integers. The
|
Note: "n", "m", "l", and "x" are 0-indexed, incrementing integers. The
|
||||||
identifier for the interfaces does not correspond to anything outside of this
|
identifier for the interfaces does not correspond to anything outside of this
|
||||||
|
@ -21,17 +21,25 @@ import (
|
|||||||
|
|
||||||
"github.com/coreos/coreos-cloudinit/config"
|
"github.com/coreos/coreos-cloudinit/config"
|
||||||
"github.com/coreos/coreos-cloudinit/datasource"
|
"github.com/coreos/coreos-cloudinit/datasource"
|
||||||
|
"github.com/coreos/coreos-cloudinit/pkg"
|
||||||
|
|
||||||
"github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/rpcvmx"
|
"github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/rpcvmx"
|
||||||
"github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/vmcheck"
|
"github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/vmcheck"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type readConfigFunction func(key string) (string, error)
|
||||||
|
type urlDownloadFunction func(url string) ([]byte, error)
|
||||||
|
|
||||||
type vmware struct {
|
type vmware struct {
|
||||||
readConfig func(key string) (string, error)
|
readConfig readConfigFunction
|
||||||
|
urlDownload urlDownloadFunction
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDatasource() *vmware {
|
func NewDatasource() *vmware {
|
||||||
return &vmware{readConfig}
|
return &vmware{
|
||||||
|
readConfig: readConfig,
|
||||||
|
urlDownload: urlDownload,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v vmware) IsAvailable() bool {
|
func (v vmware) IsAvailable() bool {
|
||||||
@ -133,6 +141,22 @@ func (v vmware) FetchUserdata() ([]byte, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try to fallback to url if no explicit data
|
||||||
|
if data == "" {
|
||||||
|
url, err := v.readConfig("coreos.config.url")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if url != "" {
|
||||||
|
rawData, err := v.urlDownload(url)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
data = string(rawData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if encoding != "" {
|
if encoding != "" {
|
||||||
return config.DecodeContent(data, encoding)
|
return config.DecodeContent(data, encoding)
|
||||||
}
|
}
|
||||||
@ -143,6 +167,11 @@ func (v vmware) Type() string {
|
|||||||
return "vmware"
|
return "vmware"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func urlDownload(url string) ([]byte, error) {
|
||||||
|
client := pkg.NewHttpClient()
|
||||||
|
return client.GetRetry(url)
|
||||||
|
}
|
||||||
|
|
||||||
func readConfig(key string) (string, error) {
|
func readConfig(key string) (string, error) {
|
||||||
data, err := rpcvmx.NewConfig().GetString(key, "")
|
data, err := rpcvmx.NewConfig().GetString(key, "")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -115,7 +115,7 @@ func TestFetchMetadata(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for i, tt := range tests {
|
for i, tt := range tests {
|
||||||
v := vmware{tt.variables.ReadConfig}
|
v := vmware{readConfig: tt.variables.ReadConfig}
|
||||||
metadata, err := v.FetchMetadata()
|
metadata, err := v.FetchMetadata()
|
||||||
if !reflect.DeepEqual(tt.err, err) {
|
if !reflect.DeepEqual(tt.err, err) {
|
||||||
t.Errorf("bad error (#%d): want %v, got %v", i, tt.err, err)
|
t.Errorf("bad error (#%d): want %v, got %v", i, tt.err, err)
|
||||||
@ -165,10 +165,37 @@ func TestFetchUserdata(t *testing.T) {
|
|||||||
},
|
},
|
||||||
err: errors.New(`Unsupported encoding "test encoding"`),
|
err: errors.New(`Unsupported encoding "test encoding"`),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
variables: map[string]string{
|
||||||
|
"coreos.config.url": "http://good.example.com",
|
||||||
|
},
|
||||||
|
userdata: "test config",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
variables: map[string]string{
|
||||||
|
"coreos.config.url": "http://bad.example.com",
|
||||||
|
},
|
||||||
|
err: errors.New("Not found"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var downloader urlDownloadFunction = func(url string) ([]byte, error) {
|
||||||
|
mapping := map[string]struct {
|
||||||
|
data []byte
|
||||||
|
err error
|
||||||
|
}{
|
||||||
|
"http://good.example.com": {[]byte("test config"), nil},
|
||||||
|
"http://bad.example.com": {nil, errors.New("Not found")},
|
||||||
|
}
|
||||||
|
val := mapping[url]
|
||||||
|
return val.data, val.err
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, tt := range tests {
|
for i, tt := range tests {
|
||||||
v := vmware{tt.variables.ReadConfig}
|
v := vmware{
|
||||||
|
readConfig: tt.variables.ReadConfig,
|
||||||
|
urlDownload: downloader,
|
||||||
|
}
|
||||||
userdata, err := v.FetchUserdata()
|
userdata, err := v.FetchUserdata()
|
||||||
if !reflect.DeepEqual(tt.err, err) {
|
if !reflect.DeepEqual(tt.err, err) {
|
||||||
t.Errorf("bad error (#%d): want %v, got %v", i, nil, err)
|
t.Errorf("bad error (#%d): want %v, got %v", i, nil, err)
|
||||||
@ -181,7 +208,7 @@ func TestFetchUserdata(t *testing.T) {
|
|||||||
|
|
||||||
func TestFetchUserdataError(t *testing.T) {
|
func TestFetchUserdataError(t *testing.T) {
|
||||||
testErr := errors.New("test error")
|
testErr := errors.New("test error")
|
||||||
_, err := vmware{func(_ string) (string, error) { return "", testErr }}.FetchUserdata()
|
_, err := vmware{readConfig: func(_ string) (string, error) { return "", testErr }}.FetchUserdata()
|
||||||
|
|
||||||
if testErr != err {
|
if testErr != err {
|
||||||
t.Errorf("bad error: want %v, got %v", testErr, err)
|
t.Errorf("bad error: want %v, got %v", testErr, err)
|
||||||
|
Loading…
Reference in New Issue
Block a user