cloudinit: retrieve IPv4 addresses from metadata
This uses the new MetadataService implementation to retrieve values for $private_ipv4 and $public_ipv4 substitutions, instead of using environment variables.
This commit is contained in:
		| @@ -86,7 +86,16 @@ func main() { | ||||
| 		die() | ||||
| 	} | ||||
|  | ||||
| 	env := initialize.NewEnvironment("/", ds.ConfigRoot(), workspace, convertNetconf, sshKeyName) | ||||
| 	var subs map[string]string | ||||
| 	if len(metadataBytes) > 0 { | ||||
| 		subs, err = initialize.ExtractIPsFromMetadata(metadataBytes) | ||||
| 		if err != nil { | ||||
| 			fmt.Printf("Failed extracting IPs from meta-data: %v\n", err) | ||||
| 			die() | ||||
| 		} | ||||
| 	} | ||||
| 	env := initialize.NewEnvironment("/", ds.ConfigRoot(), workspace, convertNetconf, sshKeyName, subs) | ||||
|  | ||||
| 	if len(userdataBytes) > 0 { | ||||
| 		if err := processUserdata(string(userdataBytes), env); err != nil { | ||||
| 			fmt.Printf("Failed to process user-data: %v\n", err) | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| package initialize | ||||
|  | ||||
| import ( | ||||
| 	"os" | ||||
| 	"path" | ||||
| 	"strings" | ||||
| ) | ||||
| @@ -17,11 +16,8 @@ type Environment struct { | ||||
| 	substitutions map[string]string | ||||
| } | ||||
|  | ||||
| func NewEnvironment(root, configRoot, workspace, netconfType, sshKeyName string) *Environment { | ||||
| 	substitutions := map[string]string{ | ||||
| 		"$public_ipv4":  os.Getenv("COREOS_PUBLIC_IPV4"), | ||||
| 		"$private_ipv4": os.Getenv("COREOS_PRIVATE_IPV4"), | ||||
| 	} | ||||
| // TODO(jonboulle): this is getting unwieldy, should be able to simplify the interface somehow | ||||
| func NewEnvironment(root, configRoot, workspace, netconfType, sshKeyName string, substitutions map[string]string) *Environment { | ||||
| 	return &Environment{root, configRoot, workspace, netconfType, sshKeyName, substitutions} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1,14 +1,13 @@ | ||||
| package initialize | ||||
|  | ||||
| import ( | ||||
| 	"os" | ||||
| 	"testing" | ||||
| ) | ||||
| import "testing" | ||||
|  | ||||
| func TestEnvironmentApply(t *testing.T) { | ||||
| 	os.Setenv("COREOS_PUBLIC_IPV4", "192.0.2.3") | ||||
| 	os.Setenv("COREOS_PRIVATE_IPV4", "192.0.2.203") | ||||
| 	env := NewEnvironment("./", "./", "./", "", "") | ||||
| 	subs := map[string]string{ | ||||
| 		"$public_ipv4":  "192.0.2.3", | ||||
| 		"$private_ipv4": "192.0.2.203", | ||||
| 	} | ||||
| 	env := NewEnvironment("./", "./", "./", "", "", subs) | ||||
| 	input := `[Service] | ||||
| ExecStart=/usr/bin/echo "$public_ipv4" | ||||
| ExecStop=/usr/bin/echo $private_ipv4 | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| package initialize | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| ) | ||||
| import "encoding/json" | ||||
|  | ||||
| // ParseMetaData parses a JSON blob in the OpenStack metadata service format, and | ||||
| // converts it to a CloudConfig | ||||
| func ParseMetaData(contents string) (cfg CloudConfig, err error) { | ||||
| 	var metadata struct { | ||||
| 		SSHAuthorizedKeyMap map[string]string `json:"public_keys"` | ||||
| @@ -24,3 +24,23 @@ func ParseMetaData(contents string) (cfg CloudConfig, err error) { | ||||
| 	cfg.NetworkConfigPath = metadata.NetworkConfig.ContentPath | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // ExtractIPsFromMetaData parses a JSON blob in the OpenStack metadata service format, | ||||
| // and returns a substitution map possibly containing private_ipv4 and public_ipv4 addresses | ||||
| func ExtractIPsFromMetadata(contents []byte) (map[string]string, error) { | ||||
| 	var ips struct { | ||||
| 		Public  string `json:"public-ipv4"` | ||||
| 		Private string `json:"local-ipv4"` | ||||
| 	} | ||||
| 	if err := json.Unmarshal(contents, &ips); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	m := make(map[string]string) | ||||
| 	if ips.Private != "" { | ||||
| 		m["$private_ipv4"] = ips.Private | ||||
| 	} | ||||
| 	if ips.Public != "" { | ||||
| 		m["$public_ipv4"] = ips.Public | ||||
| 	} | ||||
| 	return m, nil | ||||
| } | ||||
|   | ||||
							
								
								
									
										36
									
								
								initialize/meta_data_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								initialize/meta_data_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| package initialize | ||||
|  | ||||
| import "reflect" | ||||
| import "testing" | ||||
|  | ||||
| func TestExtractIPsFromMetadata(t *testing.T) { | ||||
| 	for i, tt := range []struct { | ||||
| 		in  []byte | ||||
| 		err bool | ||||
| 		out map[string]string | ||||
| 	}{ | ||||
| 		{ | ||||
| 			[]byte(`{"public-ipv4": "12.34.56.78", "local-ipv4": "1.2.3.4"}`), | ||||
| 			false, | ||||
| 			map[string]string{"$public_ipv4": "12.34.56.78", "$private_ipv4": "1.2.3.4"}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			[]byte(`{"local-ipv4": "127.0.0.1", "something_else": "don't care"}`), | ||||
| 			false, | ||||
| 			map[string]string{"$private_ipv4": "127.0.0.1"}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			[]byte(`garbage`), | ||||
| 			true, | ||||
| 			nil, | ||||
| 		}, | ||||
| 	} { | ||||
| 		got, err := ExtractIPsFromMetadata(tt.in) | ||||
| 		if (err != nil) != tt.err { | ||||
| 			t.Errorf("bad error state (got %t, want %t)", err != nil, tt.err) | ||||
| 		} | ||||
| 		if !reflect.DeepEqual(got, tt.out) { | ||||
| 			t.Errorf("case %d: got %s, want %s", i, got, tt.out) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user