initialize: change env to process from metadata
We don't use general substitutions so just have env pick the values it wants to substitute.
This commit is contained in:
parent
650a239fdb
commit
42153edbbc
@ -182,11 +182,8 @@ func main() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract IPv4 addresses from metadata
|
|
||||||
subs := initialize.ExtractIPsFromMetadata(metadata)
|
|
||||||
|
|
||||||
// Apply environment to user-data
|
// 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))
|
userdata := env.Apply(string(userdataBytes))
|
||||||
|
|
||||||
var ccu *config.CloudConfig
|
var ccu *config.CloudConfig
|
||||||
|
@ -15,12 +15,14 @@
|
|||||||
package initialize
|
package initialize
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/coreos/coreos-cloudinit/config"
|
"github.com/coreos/coreos-cloudinit/config"
|
||||||
|
"github.com/coreos/coreos-cloudinit/datasource"
|
||||||
"github.com/coreos/coreos-cloudinit/system"
|
"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
|
// 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 {
|
func NewEnvironment(root, configRoot, workspace, netconfType, sshKeyName string, metadata datasource.Metadata) *Environment {
|
||||||
if substitutions == nil {
|
firstNonNull := func(ip net.IP, env string) string {
|
||||||
substitutions = make(map[string]string)
|
if ip == nil {
|
||||||
|
return env
|
||||||
}
|
}
|
||||||
// If certain values are not in the supplied substitution, fall back to retrieving them from the environment
|
return ip.String()
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
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}
|
return &Environment{root, configRoot, workspace, netconfType, sshKeyName, substitutions}
|
||||||
}
|
}
|
||||||
|
@ -16,10 +16,12 @@ package initialize
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/coreos/coreos-cloudinit/datasource"
|
||||||
"github.com/coreos/coreos-cloudinit/system"
|
"github.com/coreos/coreos-cloudinit/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -29,18 +31,18 @@ func TestEnvironmentApply(t *testing.T) {
|
|||||||
os.Setenv("COREOS_PUBLIC_IPV6", "1234::")
|
os.Setenv("COREOS_PUBLIC_IPV6", "1234::")
|
||||||
os.Setenv("COREOS_PRIVATE_IPV6", "5678::")
|
os.Setenv("COREOS_PRIVATE_IPV6", "5678::")
|
||||||
for _, tt := range []struct {
|
for _, tt := range []struct {
|
||||||
subs map[string]string
|
metadata datasource.Metadata
|
||||||
input string
|
input string
|
||||||
out string
|
out string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
// Substituting both values directly should always take precedence
|
// Substituting both values directly should always take precedence
|
||||||
// over environment variables
|
// over environment variables
|
||||||
map[string]string{
|
datasource.Metadata{
|
||||||
"$public_ipv4": "192.0.2.3",
|
PublicIPv4: net.ParseIP("192.0.2.3"),
|
||||||
"$private_ipv4": "192.0.2.203",
|
PrivateIPv4: net.ParseIP("192.0.2.203"),
|
||||||
"$public_ipv6": "fe00:1234::",
|
PublicIPv6: net.ParseIP("fe00:1234::"),
|
||||||
"$private_ipv6": "fe00:5678::",
|
PrivateIPv6: net.ParseIP("fe00:5678::"),
|
||||||
},
|
},
|
||||||
`[Service]
|
`[Service]
|
||||||
ExecStart=/usr/bin/echo "$public_ipv4 $public_ipv6"
|
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
|
// 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",
|
"$private_ipv4\n$public_ipv4",
|
||||||
"127.0.0.1\n1.2.3.4",
|
"127.0.0.1\n1.2.3.4",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Falling back to environment variables for both values
|
// Falling back to environment variables for both values
|
||||||
map[string]string{"foo": "bar"},
|
datasource.Metadata{},
|
||||||
"$private_ipv4\n$public_ipv4",
|
"$private_ipv4\n$public_ipv4",
|
||||||
"5.6.7.8\n1.2.3.4",
|
"5.6.7.8\n1.2.3.4",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// No substitutions
|
// No substitutions
|
||||||
nil,
|
datasource.Metadata{},
|
||||||
"$private_ipv4\nfoobar",
|
"$private_ipv4\nfoobar",
|
||||||
"5.6.7.8\nfoobar",
|
"5.6.7.8\nfoobar",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Escaping substitutions
|
// Escaping substitutions
|
||||||
map[string]string{"$private_ipv4": "127.0.0.1"},
|
datasource.Metadata{
|
||||||
|
PrivateIPv4: net.ParseIP("127.0.0.1"),
|
||||||
|
},
|
||||||
`\$private_ipv4
|
`\$private_ipv4
|
||||||
$private_ipv4
|
$private_ipv4
|
||||||
addr: \$private_ipv4
|
addr: \$private_ipv4
|
||||||
@ -83,13 +89,13 @@ addr: $private_ipv4
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
// No substitutions with escaping
|
// No substitutions with escaping
|
||||||
nil,
|
datasource.Metadata{},
|
||||||
"\\$test\n$test",
|
"\\$test\n$test",
|
||||||
"\\$test\n$test",
|
"\\$test\n$test",
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
|
|
||||||
env := NewEnvironment("./", "./", "./", "", "", tt.subs)
|
env := NewEnvironment("./", "./", "./", "", "", tt.metadata)
|
||||||
got := env.Apply(tt.input)
|
got := env.Apply(tt.input)
|
||||||
if got != tt.out {
|
if got != tt.out {
|
||||||
t.Fatalf("Environment incorrectly applied.\ngot:\n%s\nwant:\n%s", 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) {
|
func TestEnvironmentFile(t *testing.T) {
|
||||||
subs := map[string]string{
|
metadata := datasource.Metadata{
|
||||||
"$public_ipv4": "1.2.3.4",
|
PublicIPv4: net.ParseIP("1.2.3.4"),
|
||||||
"$private_ipv4": "5.6.7.8",
|
PrivateIPv4: net.ParseIP("5.6.7.8"),
|
||||||
"$public_ipv6": "1234::",
|
PublicIPv6: net.ParseIP("1234::"),
|
||||||
"$private_ipv6": "5678::",
|
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"
|
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)
|
defer os.RemoveAll(dir)
|
||||||
|
|
||||||
env := NewEnvironment("./", "./", "./", "", "", subs)
|
env := NewEnvironment("./", "./", "./", "", "", metadata)
|
||||||
ef := env.DefaultEnvironmentFile()
|
ef := env.DefaultEnvironmentFile()
|
||||||
err = system.WriteEnvFile(ef, dir)
|
err = system.WriteEnvFile(ef, dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -131,14 +137,10 @@ func TestEnvironmentFile(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestEnvironmentFileNil(t *testing.T) {
|
func TestEnvironmentFileNil(t *testing.T) {
|
||||||
subs := map[string]string{
|
os.Clearenv()
|
||||||
"$public_ipv4": "",
|
metadata := datasource.Metadata{}
|
||||||
"$private_ipv4": "",
|
|
||||||
"$public_ipv6": "",
|
|
||||||
"$private_ipv6": "",
|
|
||||||
}
|
|
||||||
|
|
||||||
env := NewEnvironment("./", "./", "./", "", "", subs)
|
env := NewEnvironment("./", "./", "./", "", "", metadata)
|
||||||
ef := env.DefaultEnvironmentFile()
|
ef := env.DefaultEnvironmentFile()
|
||||||
if ef != nil {
|
if ef != nil {
|
||||||
t.Fatalf("Environment file not nil: %v", ef)
|
t.Fatalf("Environment file not nil: %v", ef)
|
||||||
|
@ -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
|
|
||||||
}
|
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user