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"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/coreos/coreos-cloudinit/pkg"
|
"github.com/coreos/coreos-cloudinit/pkg"
|
||||||
@ -23,7 +24,7 @@ const (
|
|||||||
BaseUrl = "http://169.254.169.254/"
|
BaseUrl = "http://169.254.169.254/"
|
||||||
Ec2ApiVersion = "2009-04-04"
|
Ec2ApiVersion = "2009-04-04"
|
||||||
Ec2UserdataUrl = BaseUrl + Ec2ApiVersion + "/user-data"
|
Ec2UserdataUrl = BaseUrl + Ec2ApiVersion + "/user-data"
|
||||||
Ec2MetadataUrl = BaseUrl + Ec2ApiVersion + "/meta-data/"
|
Ec2MetadataUrl = BaseUrl + Ec2ApiVersion + "/meta-data"
|
||||||
OpenstackApiVersion = "openstack/2012-08-10"
|
OpenstackApiVersion = "openstack/2012-08-10"
|
||||||
OpenstackUserdataUrl = BaseUrl + OpenstackApiVersion + "/user_data"
|
OpenstackUserdataUrl = BaseUrl + OpenstackApiVersion + "/user_data"
|
||||||
OpenstackMetadataUrl = BaseUrl + OpenstackApiVersion + "/meta_data.json"
|
OpenstackMetadataUrl = BaseUrl + OpenstackApiVersion + "/meta_data.json"
|
||||||
@ -78,10 +79,45 @@ func fetchMetadata(client getter) ([]byte, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
attrs, err := fetchChildAttributes(client, Ec2MetadataUrl)
|
attrs := make(map[string]interface{})
|
||||||
if err != nil {
|
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
|
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)
|
return json.Marshal(attrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,37 +129,15 @@ func fetchAttributes(client getter, url string) ([]string, error) {
|
|||||||
scanner := bufio.NewScanner(bytes.NewBuffer(resp))
|
scanner := bufio.NewScanner(bytes.NewBuffer(resp))
|
||||||
data := make([]string, 0)
|
data := make([]string, 0)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
data = append(data, strings.Split(scanner.Text(), "=")[0])
|
data = append(data, scanner.Text())
|
||||||
}
|
}
|
||||||
return data, scanner.Err()
|
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 {
|
if attrs, err := fetchAttributes(client, url); err == nil && len(attrs) > 0 {
|
||||||
return attrs[0], nil
|
return attrs[0], nil
|
||||||
} else {
|
} else {
|
||||||
return "", err
|
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{
|
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/hostname": "host",
|
||||||
"http://169.254.169.254/2009-04-04/meta-data/c/": "d\ne/",
|
"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/c/e/": "f",
|
"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/a": "1",
|
"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/b": "2",
|
"http://169.254.169.254/2009-04-04/meta-data/network_config/content_path": "path",
|
||||||
"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",
|
|
||||||
},
|
},
|
||||||
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{
|
metadata: map[string]string{
|
||||||
@ -154,7 +152,6 @@ func TestFetchMetadata(t *testing.T) {
|
|||||||
expect: []byte("test"),
|
expect: []byte("test"),
|
||||||
},
|
},
|
||||||
{err: pkg.ErrTimeout{fmt.Errorf("test error")}},
|
{err: pkg.ErrTimeout{fmt.Errorf("test error")}},
|
||||||
{err: pkg.ErrNotFound{fmt.Errorf("test error")}},
|
|
||||||
} {
|
} {
|
||||||
client := &TestHttpClient{tt.metadata, tt.err}
|
client := &TestHttpClient{tt.metadata, tt.err}
|
||||||
metadata, err := fetchMetadata(client)
|
metadata, err := fetchMetadata(client)
|
||||||
|
Loading…
Reference in New Issue
Block a user