From 42153edbbc49333c456ff8f6f10630d8037c3d6d Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Mon, 26 Jan 2015 15:45:15 -0800 Subject: [PATCH] initialize: change env to process from metadata We don't use general substitutions so just have env pick the values it wants to substitute. --- coreos-cloudinit.go | 5 +--- initialize/env.go | 26 ++++++++--------- initialize/env_test.go | 56 +++++++++++++++++++----------------- initialize/meta_data.go | 50 -------------------------------- initialize/meta_data_test.go | 45 ----------------------------- 5 files changed, 43 insertions(+), 139 deletions(-) delete mode 100644 initialize/meta_data.go delete mode 100644 initialize/meta_data_test.go diff --git a/coreos-cloudinit.go b/coreos-cloudinit.go index cc2be1e..fefc3dc 100644 --- a/coreos-cloudinit.go +++ b/coreos-cloudinit.go @@ -182,11 +182,8 @@ func main() { os.Exit(1) } - // Extract IPv4 addresses from metadata - subs := initialize.ExtractIPsFromMetadata(metadata) - // Apply environment to user-data - env := initialize.NewEnvironment("/", ds.ConfigRoot(), flags.workspace, flags.convertNetconf, flags.sshKeyName, subs) + env := initialize.NewEnvironment("/", ds.ConfigRoot(), flags.workspace, flags.convertNetconf, flags.sshKeyName, metadata) userdata := env.Apply(string(userdataBytes)) var ccu *config.CloudConfig diff --git a/initialize/env.go b/initialize/env.go index 0c6e0bb..fc9411f 100644 --- a/initialize/env.go +++ b/initialize/env.go @@ -15,12 +15,14 @@ package initialize import ( + "net" "os" "path" "regexp" "strings" "github.com/coreos/coreos-cloudinit/config" + "github.com/coreos/coreos-cloudinit/datasource" "github.com/coreos/coreos-cloudinit/system" ) @@ -36,20 +38,18 @@ type Environment struct { } // 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 { - if substitutions == nil { - substitutions = make(map[string]string) - } - // If certain values are not in the supplied substitution, fall back to retrieving them from the environment - for k, v := range map[string]string{ - "$public_ipv4": os.Getenv("COREOS_PUBLIC_IPV4"), - "$private_ipv4": os.Getenv("COREOS_PRIVATE_IPV4"), - "$public_ipv6": os.Getenv("COREOS_PUBLIC_IPV6"), - "$private_ipv6": os.Getenv("COREOS_PRIVATE_IPV6"), - } { - if _, ok := substitutions[k]; !ok { - substitutions[k] = v +func NewEnvironment(root, configRoot, workspace, netconfType, sshKeyName string, metadata datasource.Metadata) *Environment { + firstNonNull := func(ip net.IP, env string) string { + if ip == nil { + return env } + return ip.String() + } + substitutions := map[string]string{ + "$public_ipv4": firstNonNull(metadata.PublicIPv4, os.Getenv("COREOS_PUBLIC_IPV4")), + "$private_ipv4": firstNonNull(metadata.PrivateIPv4, os.Getenv("COREOS_PRIVATE_IPV4")), + "$public_ipv6": firstNonNull(metadata.PublicIPv6, os.Getenv("COREOS_PUBLIC_IPV6")), + "$private_ipv6": firstNonNull(metadata.PrivateIPv6, os.Getenv("COREOS_PRIVATE_IPV6")), } return &Environment{root, configRoot, workspace, netconfType, sshKeyName, substitutions} } diff --git a/initialize/env_test.go b/initialize/env_test.go index f21aa97..d56916a 100644 --- a/initialize/env_test.go +++ b/initialize/env_test.go @@ -16,10 +16,12 @@ package initialize import ( "io/ioutil" + "net" "os" "path" "testing" + "github.com/coreos/coreos-cloudinit/datasource" "github.com/coreos/coreos-cloudinit/system" ) @@ -29,18 +31,18 @@ func TestEnvironmentApply(t *testing.T) { os.Setenv("COREOS_PUBLIC_IPV6", "1234::") os.Setenv("COREOS_PRIVATE_IPV6", "5678::") for _, tt := range []struct { - subs map[string]string - input string - out string + metadata datasource.Metadata + input string + out string }{ { // Substituting both values directly should always take precedence // over environment variables - map[string]string{ - "$public_ipv4": "192.0.2.3", - "$private_ipv4": "192.0.2.203", - "$public_ipv6": "fe00:1234::", - "$private_ipv6": "fe00:5678::", + datasource.Metadata{ + PublicIPv4: net.ParseIP("192.0.2.3"), + PrivateIPv4: net.ParseIP("192.0.2.203"), + PublicIPv6: net.ParseIP("fe00:1234::"), + PrivateIPv6: net.ParseIP("fe00:5678::"), }, `[Service] ExecStart=/usr/bin/echo "$public_ipv4 $public_ipv6" @@ -53,25 +55,29 @@ ExecStop=/usr/bin/echo $unknown`, }, { // Substituting one value directly while falling back with the other - map[string]string{"$private_ipv4": "127.0.0.1"}, + datasource.Metadata{ + PrivateIPv4: net.ParseIP("127.0.0.1"), + }, "$private_ipv4\n$public_ipv4", "127.0.0.1\n1.2.3.4", }, { // Falling back to environment variables for both values - map[string]string{"foo": "bar"}, + datasource.Metadata{}, "$private_ipv4\n$public_ipv4", "5.6.7.8\n1.2.3.4", }, { // No substitutions - nil, + datasource.Metadata{}, "$private_ipv4\nfoobar", "5.6.7.8\nfoobar", }, { // Escaping substitutions - map[string]string{"$private_ipv4": "127.0.0.1"}, + datasource.Metadata{ + PrivateIPv4: net.ParseIP("127.0.0.1"), + }, `\$private_ipv4 $private_ipv4 addr: \$private_ipv4 @@ -83,13 +89,13 @@ addr: $private_ipv4 }, { // No substitutions with escaping - nil, + datasource.Metadata{}, "\\$test\n$test", "\\$test\n$test", }, } { - env := NewEnvironment("./", "./", "./", "", "", tt.subs) + env := NewEnvironment("./", "./", "./", "", "", tt.metadata) got := env.Apply(tt.input) if got != tt.out { t.Fatalf("Environment incorrectly applied.\ngot:\n%s\nwant:\n%s", got, tt.out) @@ -98,11 +104,11 @@ addr: $private_ipv4 } func TestEnvironmentFile(t *testing.T) { - subs := map[string]string{ - "$public_ipv4": "1.2.3.4", - "$private_ipv4": "5.6.7.8", - "$public_ipv6": "1234::", - "$private_ipv6": "5678::", + metadata := datasource.Metadata{ + PublicIPv4: net.ParseIP("1.2.3.4"), + PrivateIPv4: net.ParseIP("5.6.7.8"), + PublicIPv6: net.ParseIP("1234::"), + PrivateIPv6: net.ParseIP("5678::"), } expect := "COREOS_PRIVATE_IPV4=5.6.7.8\nCOREOS_PRIVATE_IPV6=5678::\nCOREOS_PUBLIC_IPV4=1.2.3.4\nCOREOS_PUBLIC_IPV6=1234::\n" @@ -112,7 +118,7 @@ func TestEnvironmentFile(t *testing.T) { } defer os.RemoveAll(dir) - env := NewEnvironment("./", "./", "./", "", "", subs) + env := NewEnvironment("./", "./", "./", "", "", metadata) ef := env.DefaultEnvironmentFile() err = system.WriteEnvFile(ef, dir) if err != nil { @@ -131,14 +137,10 @@ func TestEnvironmentFile(t *testing.T) { } func TestEnvironmentFileNil(t *testing.T) { - subs := map[string]string{ - "$public_ipv4": "", - "$private_ipv4": "", - "$public_ipv6": "", - "$private_ipv6": "", - } + os.Clearenv() + metadata := datasource.Metadata{} - env := NewEnvironment("./", "./", "./", "", "", subs) + env := NewEnvironment("./", "./", "./", "", "", metadata) ef := env.DefaultEnvironmentFile() if ef != nil { t.Fatalf("Environment file not nil: %v", ef) diff --git a/initialize/meta_data.go b/initialize/meta_data.go deleted file mode 100644 index fb92b19..0000000 --- a/initialize/meta_data.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package initialize - -import ( - "sort" - - "github.com/coreos/coreos-cloudinit/datasource" -) - -// ExtractIPsFromMetaData parses a JSON blob in the OpenStack metadata service -// format and returns a substitution map possibly containing private_ipv4, -// public_ipv4, private_ipv6, and public_ipv6 addresses. -func ExtractIPsFromMetadata(metadata datasource.Metadata) map[string]string { - subs := map[string]string{} - if metadata.PrivateIPv4 != nil { - subs["$private_ipv4"] = metadata.PrivateIPv4.String() - } - if metadata.PublicIPv4 != nil { - subs["$public_ipv4"] = metadata.PublicIPv4.String() - } - if metadata.PrivateIPv6 != nil { - subs["$private_ipv6"] = metadata.PrivateIPv6.String() - } - if metadata.PublicIPv6 != nil { - subs["$public_ipv6"] = metadata.PublicIPv6.String() - } - - return subs -} - -func sortedKeys(m map[string]string) (keys []string) { - for key := range m { - keys = append(keys, key) - } - sort.Strings(keys) - return -} diff --git a/initialize/meta_data_test.go b/initialize/meta_data_test.go deleted file mode 100644 index 15c08a0..0000000 --- a/initialize/meta_data_test.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package initialize - -import ( - "net" - "reflect" - "testing" - - "github.com/coreos/coreos-cloudinit/datasource" -) - -func TestExtractIPsFromMetadata(t *testing.T) { - for i, tt := range []struct { - in datasource.Metadata - out map[string]string - }{ - { - datasource.Metadata{ - PublicIPv4: net.ParseIP("12.34.56.78"), - PrivateIPv4: net.ParseIP("1.2.3.4"), - PublicIPv6: net.ParseIP("1234::"), - PrivateIPv6: net.ParseIP("5678::"), - }, - map[string]string{"$public_ipv4": "12.34.56.78", "$private_ipv4": "1.2.3.4", "$public_ipv6": "1234::", "$private_ipv6": "5678::"}, - }, - } { - got := ExtractIPsFromMetadata(tt.in) - if !reflect.DeepEqual(got, tt.out) { - t.Errorf("case %d: got %s, want %s", i, got, tt.out) - } - } -}