metadata-service: fix ssh key retrieval and application
The metadata service wasn't properly fetching the ssh keys from metadata. Drop the key traversal in favor of explict key urls.
This commit is contained in:
parent
cb7fbd4668
commit
7fcc540154
@ -4,6 +4,7 @@ import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/coreos/coreos-cloudinit/pkg"
|
||||
@ -23,7 +24,7 @@ const (
|
||||
BaseUrl = "http://169.254.169.254/"
|
||||
Ec2ApiVersion = "2009-04-04"
|
||||
Ec2UserdataUrl = BaseUrl + Ec2ApiVersion + "/user-data"
|
||||
Ec2MetadataUrl = BaseUrl + Ec2ApiVersion + "/meta-data/"
|
||||
Ec2MetadataUrl = BaseUrl + Ec2ApiVersion + "/meta-data"
|
||||
OpenstackApiVersion = "openstack/2012-08-10"
|
||||
OpenstackUserdataUrl = BaseUrl + OpenstackApiVersion + "/user_data"
|
||||
OpenstackMetadataUrl = BaseUrl + OpenstackApiVersion + "/meta_data.json"
|
||||
@ -78,10 +79,45 @@ func fetchMetadata(client getter) ([]byte, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
attrs, err := fetchChildAttributes(client, Ec2MetadataUrl)
|
||||
if err != nil {
|
||||
attrs := make(map[string]interface{})
|
||||
if keynames, err := fetchAttributes(client, fmt.Sprintf("%s/public-keys", Ec2MetadataUrl)); err == nil {
|
||||
keyIDs := make(map[string]string)
|
||||
for _, keyname := range keynames {
|
||||
tokens := strings.SplitN(keyname, "=", 2)
|
||||
if len(tokens) != 2 {
|
||||
return nil, fmt.Errorf("malformed public key: %q\n", keyname)
|
||||
}
|
||||
keyIDs[tokens[1]] = tokens[0]
|
||||
}
|
||||
|
||||
keys := make(map[string]string)
|
||||
for name, id := range keyIDs {
|
||||
sshkey, err := fetchAttribute(client, fmt.Sprintf("%s/public-keys/%s/openssh-key", Ec2MetadataUrl, id))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
keys[name] = sshkey
|
||||
fmt.Printf("Found SSH key for %q\n", name)
|
||||
}
|
||||
attrs["public_keys"] = keys
|
||||
} else if _, ok := err.(pkg.ErrNotFound); !ok {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if hostname, err := fetchAttribute(client, fmt.Sprintf("%s/hostname", Ec2MetadataUrl)); err == nil {
|
||||
attrs["hostname"] = hostname
|
||||
} else if _, ok := err.(pkg.ErrNotFound); !ok {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if content_path, err := fetchAttribute(client, fmt.Sprintf("%s/network_config/content_path", Ec2MetadataUrl)); err == nil {
|
||||
attrs["network_config"] = map[string]string{
|
||||
"content_path": content_path,
|
||||
}
|
||||
} else if _, ok := err.(pkg.ErrNotFound); !ok {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return json.Marshal(attrs)
|
||||
}
|
||||
|
||||
@ -93,37 +129,15 @@ func fetchAttributes(client getter, url string) ([]string, error) {
|
||||
scanner := bufio.NewScanner(bytes.NewBuffer(resp))
|
||||
data := make([]string, 0)
|
||||
for scanner.Scan() {
|
||||
data = append(data, strings.Split(scanner.Text(), "=")[0])
|
||||
data = append(data, scanner.Text())
|
||||
}
|
||||
return data, scanner.Err()
|
||||
}
|
||||
|
||||
func fetchAttribute(client getter, url string) (interface{}, error) {
|
||||
func fetchAttribute(client getter, url string) (string, error) {
|
||||
if attrs, err := fetchAttributes(client, url); err == nil && len(attrs) > 0 {
|
||||
return attrs[0], nil
|
||||
} else {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
func fetchChildAttributes(client getter, url string) (interface{}, error) {
|
||||
attrs := make(map[string]interface{})
|
||||
attrList, err := fetchAttributes(client, url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, attr := range attrList {
|
||||
var fetchFunc func(getter, string) (interface{}, error)
|
||||
if strings.HasSuffix(attr, "/") {
|
||||
fetchFunc = fetchChildAttributes
|
||||
} else {
|
||||
fetchFunc = fetchAttribute
|
||||
}
|
||||
if value, err := fetchFunc(client, url+attr); err == nil {
|
||||
attrs[strings.TrimSuffix(attr, "/")] = value
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return attrs, nil
|
||||
}
|
||||
|
@ -137,15 +137,13 @@ func TestFetchMetadata(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
metadata: map[string]string{
|
||||
"http://169.254.169.254/2009-04-04/meta-data/": "a\nb\nc/",
|
||||
"http://169.254.169.254/2009-04-04/meta-data/c/": "d\ne/",
|
||||
"http://169.254.169.254/2009-04-04/meta-data/c/e/": "f",
|
||||
"http://169.254.169.254/2009-04-04/meta-data/a": "1",
|
||||
"http://169.254.169.254/2009-04-04/meta-data/b": "2",
|
||||
"http://169.254.169.254/2009-04-04/meta-data/c/d": "3",
|
||||
"http://169.254.169.254/2009-04-04/meta-data/c/e/f": "4",
|
||||
"http://169.254.169.254/2009-04-04/meta-data/hostname": "host",
|
||||
"http://169.254.169.254/2009-04-04/meta-data/public-keys": "0=test1\n",
|
||||
"http://169.254.169.254/2009-04-04/meta-data/public-keys/0": "openssh-key",
|
||||
"http://169.254.169.254/2009-04-04/meta-data/public-keys/0/openssh-key": "key",
|
||||
"http://169.254.169.254/2009-04-04/meta-data/network_config/content_path": "path",
|
||||
},
|
||||
expect: []byte(`{"a":"1","b":"2","c":{"d":"3","e":{"f":"4"}}}`),
|
||||
expect: []byte(`{"hostname":"host","network_config":{"content_path":"path"},"public_keys":{"test1":"key"}}`),
|
||||
},
|
||||
{
|
||||
metadata: map[string]string{
|
||||
@ -154,7 +152,6 @@ func TestFetchMetadata(t *testing.T) {
|
||||
expect: []byte("test"),
|
||||
},
|
||||
{err: pkg.ErrTimeout{fmt.Errorf("test error")}},
|
||||
{err: pkg.ErrNotFound{fmt.Errorf("test error")}},
|
||||
} {
|
||||
client := &TestHttpClient{tt.metadata, tt.err}
|
||||
metadata, err := fetchMetadata(client)
|
||||
|
Loading…
Reference in New Issue
Block a user