2014-03-18 20:00:41 +04:00
|
|
|
package initialize
|
2014-03-05 04:36:05 +04:00
|
|
|
|
|
|
|
import (
|
2014-05-10 12:06:38 +04:00
|
|
|
"fmt"
|
2014-03-13 03:52:32 +04:00
|
|
|
"strings"
|
2014-03-05 04:36:05 +04:00
|
|
|
"testing"
|
|
|
|
)
|
|
|
|
|
2014-05-10 12:06:38 +04:00
|
|
|
func TestCloudConfigUnknownKeys(t *testing.T) {
|
|
|
|
contents := `
|
|
|
|
coreos:
|
|
|
|
etcd:
|
|
|
|
discovery: "https://discovery.etcd.io/827c73219eeb2fa5530027c37bf18877"
|
2014-05-13 02:46:38 +04:00
|
|
|
coreos_unknown:
|
|
|
|
foo: "bar"
|
|
|
|
section_unknown:
|
2014-05-10 12:06:38 +04:00
|
|
|
dunno:
|
|
|
|
something
|
2014-05-13 02:46:38 +04:00
|
|
|
bare_unknown:
|
2014-05-10 12:06:38 +04:00
|
|
|
bar
|
2014-05-13 03:33:28 +04:00
|
|
|
write_files:
|
|
|
|
- content: fun
|
|
|
|
path: /var/party
|
|
|
|
file_unknown: nofun
|
|
|
|
users:
|
|
|
|
- name: fry
|
|
|
|
passwd: somehash
|
|
|
|
user_unknown: philip
|
2014-05-10 12:06:38 +04:00
|
|
|
hostname:
|
|
|
|
foo
|
|
|
|
`
|
|
|
|
cfg, err := NewCloudConfig(contents)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error instantiating CloudConfig with unknown keys: %v", err)
|
|
|
|
}
|
|
|
|
if cfg.Hostname != "foo" {
|
|
|
|
t.Fatalf("hostname not correctly set when invalid keys are present")
|
|
|
|
}
|
|
|
|
if len(cfg.Coreos.Etcd) < 1 {
|
|
|
|
t.Fatalf("etcd section not correctly set when invalid keys are present")
|
|
|
|
}
|
2014-05-13 03:33:28 +04:00
|
|
|
if len(cfg.WriteFiles) < 1 || cfg.WriteFiles[0].Content != "fun" || cfg.WriteFiles[0].Path != "/var/party" {
|
|
|
|
t.Fatalf("write_files section not correctly set when invalid keys are present")
|
|
|
|
}
|
|
|
|
if len(cfg.Users) < 1 || cfg.Users[0].Name != "fry" || cfg.Users[0].PasswordHash != "somehash" {
|
|
|
|
t.Fatalf("users section not correctly set when invalid keys are present")
|
|
|
|
}
|
2014-05-10 12:06:38 +04:00
|
|
|
|
|
|
|
var warnings string
|
|
|
|
catchWarn := func(f string, v ...interface{}) {
|
|
|
|
warnings += fmt.Sprintf(f, v...)
|
|
|
|
}
|
|
|
|
|
|
|
|
warnOnUnrecognizedKeys(contents, catchWarn)
|
|
|
|
|
2014-05-13 02:46:38 +04:00
|
|
|
if !strings.Contains(warnings, "coreos_unknown") {
|
|
|
|
t.Errorf("warnings did not catch unrecognized coreos option coreos_unknown")
|
2014-05-10 12:06:38 +04:00
|
|
|
}
|
2014-05-13 02:46:38 +04:00
|
|
|
if !strings.Contains(warnings, "bare_unknown") {
|
|
|
|
t.Errorf("warnings did not catch unrecognized key bare_unknown")
|
|
|
|
}
|
|
|
|
if !strings.Contains(warnings, "section_unknown") {
|
|
|
|
t.Errorf("warnings did not catch unrecognized key section_unknown")
|
2014-05-10 12:06:38 +04:00
|
|
|
}
|
2014-05-13 03:33:28 +04:00
|
|
|
if !strings.Contains(warnings, "user_unknown") {
|
|
|
|
t.Errorf("warnings did not catch unrecognized user key user_unknown")
|
|
|
|
}
|
|
|
|
if !strings.Contains(warnings, "file_unknown") {
|
|
|
|
t.Errorf("warnings did not catch unrecognized file key file_unknown")
|
|
|
|
}
|
2014-05-10 12:06:38 +04:00
|
|
|
}
|
|
|
|
|
2014-03-05 04:36:05 +04:00
|
|
|
// Assert that the parsing of a cloud config file "generally works"
|
|
|
|
func TestCloudConfigEmpty(t *testing.T) {
|
2014-03-21 21:35:18 +04:00
|
|
|
cfg, err := NewCloudConfig("")
|
2014-03-05 04:36:05 +04:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Encountered unexpected error :%v", err)
|
|
|
|
}
|
|
|
|
|
2014-03-13 22:39:31 +04:00
|
|
|
keys := cfg.SSHAuthorizedKeys
|
2014-03-05 04:36:05 +04:00
|
|
|
if len(keys) != 0 {
|
|
|
|
t.Error("Parsed incorrect number of SSH keys")
|
|
|
|
}
|
|
|
|
|
2014-03-13 22:40:33 +04:00
|
|
|
if len(cfg.WriteFiles) != 0 {
|
|
|
|
t.Error("Expected zero WriteFiles")
|
2014-03-12 04:46:58 +04:00
|
|
|
}
|
2014-03-13 09:30:24 +04:00
|
|
|
|
|
|
|
if cfg.Hostname != "" {
|
|
|
|
t.Errorf("Expected hostname to be empty, got '%s'", cfg.Hostname)
|
|
|
|
}
|
2014-03-05 04:36:05 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Assert that the parsing of a cloud config file "generally works"
|
|
|
|
func TestCloudConfig(t *testing.T) {
|
2014-03-21 21:35:18 +04:00
|
|
|
contents := `
|
2014-03-05 04:36:05 +04:00
|
|
|
coreos:
|
|
|
|
etcd:
|
2014-03-19 00:01:10 +04:00
|
|
|
discovery: "https://discovery.etcd.io/827c73219eeb2fa5530027c37bf18877"
|
2014-05-07 04:44:18 +04:00
|
|
|
update:
|
|
|
|
reboot-strategy: reboot
|
2014-03-13 02:43:51 +04:00
|
|
|
units:
|
|
|
|
- name: 50-eth0.network
|
|
|
|
runtime: yes
|
|
|
|
content: '[Match]
|
|
|
|
|
|
|
|
Name=eth47
|
|
|
|
|
|
|
|
|
|
|
|
[Network]
|
|
|
|
|
|
|
|
Address=10.209.171.177/19
|
|
|
|
|
|
|
|
'
|
2014-03-23 22:06:43 +04:00
|
|
|
oem:
|
|
|
|
id: rackspace
|
|
|
|
name: Rackspace Cloud Servers
|
|
|
|
version-id: 168.0.0
|
|
|
|
home-url: https://www.rackspace.com/cloud/servers/
|
|
|
|
bug-report-url: https://github.com/coreos/coreos-overlay
|
2014-03-05 04:36:05 +04:00
|
|
|
ssh_authorized_keys:
|
|
|
|
- foobar
|
|
|
|
- foobaz
|
2014-03-12 04:46:58 +04:00
|
|
|
write_files:
|
|
|
|
- content: |
|
|
|
|
penny
|
|
|
|
elroy
|
|
|
|
path: /etc/dogepack.conf
|
|
|
|
permissions: '0644'
|
|
|
|
owner: root:dogepack
|
2014-03-13 09:30:24 +04:00
|
|
|
hostname: trontastic
|
2014-03-21 21:35:18 +04:00
|
|
|
`
|
2014-03-05 04:36:05 +04:00
|
|
|
cfg, err := NewCloudConfig(contents)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Encountered unexpected error :%v", err)
|
|
|
|
}
|
|
|
|
|
2014-03-13 22:39:31 +04:00
|
|
|
keys := cfg.SSHAuthorizedKeys
|
2014-03-05 04:36:05 +04:00
|
|
|
if len(keys) != 2 {
|
|
|
|
t.Error("Parsed incorrect number of SSH keys")
|
|
|
|
} else if keys[0] != "foobar" {
|
|
|
|
t.Error("Expected first SSH key to be 'foobar'")
|
|
|
|
} else if keys[1] != "foobaz" {
|
|
|
|
t.Error("Expected first SSH key to be 'foobaz'")
|
|
|
|
}
|
|
|
|
|
2014-03-13 22:40:33 +04:00
|
|
|
if len(cfg.WriteFiles) != 1 {
|
2014-03-12 04:46:58 +04:00
|
|
|
t.Error("Failed to parse correct number of write_files")
|
|
|
|
} else {
|
2014-03-13 22:40:33 +04:00
|
|
|
wf := cfg.WriteFiles[0]
|
2014-03-12 04:46:58 +04:00
|
|
|
if wf.Content != "penny\nelroy\n" {
|
|
|
|
t.Errorf("WriteFile has incorrect contents '%s'", wf.Content)
|
|
|
|
}
|
|
|
|
if wf.Encoding != "" {
|
|
|
|
t.Errorf("WriteFile has incorrect encoding %s", wf.Encoding)
|
|
|
|
}
|
2014-03-18 04:05:59 +04:00
|
|
|
if perm, _ := wf.Permissions(); perm != 0644 {
|
|
|
|
t.Errorf("WriteFile has incorrect permissions %s", perm)
|
2014-03-12 04:46:58 +04:00
|
|
|
}
|
|
|
|
if wf.Path != "/etc/dogepack.conf" {
|
|
|
|
t.Errorf("WriteFile has incorrect path %s", wf.Path)
|
|
|
|
}
|
|
|
|
if wf.Owner != "root:dogepack" {
|
|
|
|
t.Errorf("WriteFile has incorrect owner %s", wf.Owner)
|
|
|
|
}
|
|
|
|
}
|
2014-03-13 02:43:51 +04:00
|
|
|
|
|
|
|
if len(cfg.Coreos.Units) != 1 {
|
|
|
|
t.Error("Failed to parse correct number of units")
|
|
|
|
} else {
|
|
|
|
u := cfg.Coreos.Units[0]
|
|
|
|
expect := `[Match]
|
|
|
|
Name=eth47
|
|
|
|
|
|
|
|
[Network]
|
|
|
|
Address=10.209.171.177/19
|
|
|
|
`
|
|
|
|
if u.Content != expect {
|
|
|
|
t.Errorf("Unit has incorrect contents '%s'.\nExpected '%s'.", u.Content, expect)
|
|
|
|
}
|
|
|
|
if u.Runtime != true {
|
|
|
|
t.Errorf("Unit has incorrect runtime value")
|
|
|
|
}
|
|
|
|
if u.Name != "50-eth0.network" {
|
|
|
|
t.Errorf("Unit has incorrect name %s", u.Name)
|
|
|
|
}
|
|
|
|
if u.Type() != "network" {
|
|
|
|
t.Errorf("Unit has incorrect type '%s'", u.Type())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-23 22:06:43 +04:00
|
|
|
if cfg.Coreos.OEM.ID != "rackspace" {
|
|
|
|
t.Errorf("Failed parsing coreos.oem. Expected ID 'rackspace', got %q.", cfg.Coreos.OEM.ID)
|
|
|
|
}
|
|
|
|
|
2014-03-13 09:30:24 +04:00
|
|
|
if cfg.Hostname != "trontastic" {
|
|
|
|
t.Errorf("Failed to parse hostname")
|
|
|
|
}
|
2014-05-07 04:44:18 +04:00
|
|
|
if cfg.Coreos.Update["reboot-strategy"] != "reboot" {
|
|
|
|
t.Errorf("Failed to parse locksmith strategy")
|
|
|
|
}
|
2014-03-05 04:36:05 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Assert that our interface conversion doesn't panic
|
|
|
|
func TestCloudConfigKeysNotList(t *testing.T) {
|
2014-03-21 21:35:18 +04:00
|
|
|
contents := `
|
2014-03-05 04:36:05 +04:00
|
|
|
ssh_authorized_keys:
|
|
|
|
- foo: bar
|
2014-03-21 21:35:18 +04:00
|
|
|
`
|
2014-03-05 04:36:05 +04:00
|
|
|
cfg, err := NewCloudConfig(contents)
|
|
|
|
if err != nil {
|
2014-05-13 02:20:08 +04:00
|
|
|
t.Fatalf("Encountered unexpected error: %v", err)
|
2014-03-05 04:36:05 +04:00
|
|
|
}
|
|
|
|
|
2014-03-13 22:39:31 +04:00
|
|
|
keys := cfg.SSHAuthorizedKeys
|
2014-03-05 04:36:05 +04:00
|
|
|
if len(keys) != 0 {
|
|
|
|
t.Error("Parsed incorrect number of SSH keys")
|
|
|
|
}
|
|
|
|
}
|
2014-03-13 03:52:32 +04:00
|
|
|
|
|
|
|
func TestCloudConfigSerializationHeader(t *testing.T) {
|
2014-03-21 21:35:18 +04:00
|
|
|
cfg, _ := NewCloudConfig("")
|
2014-03-13 03:52:32 +04:00
|
|
|
contents := cfg.String()
|
|
|
|
header := strings.SplitN(contents, "\n", 2)[0]
|
|
|
|
if header != "#cloud-config" {
|
|
|
|
t.Fatalf("Serialized config did not have expected header")
|
|
|
|
}
|
|
|
|
}
|
2014-03-13 21:56:59 +04:00
|
|
|
|
2014-05-13 02:20:08 +04:00
|
|
|
// TestDropInIgnored asserts that users are unable to set DropIn=True on units
|
|
|
|
func TestDropInIgnored(t *testing.T) {
|
|
|
|
contents := `
|
|
|
|
coreos:
|
|
|
|
units:
|
|
|
|
- name: test
|
|
|
|
dropin: true
|
|
|
|
`
|
|
|
|
cfg, err := NewCloudConfig(contents)
|
|
|
|
if err != nil || len(cfg.Coreos.Units) != 1 {
|
|
|
|
t.Fatalf("Encountered unexpected error: %v", err)
|
|
|
|
}
|
|
|
|
if len(cfg.Coreos.Units) != 1 || cfg.Coreos.Units[0].Name != "test" {
|
|
|
|
t.Fatalf("Expected 1 unit, but got %d: %v", len(cfg.Coreos.Units), cfg.Coreos.Units)
|
|
|
|
}
|
|
|
|
if cfg.Coreos.Units[0].DropIn {
|
|
|
|
t.Errorf("dropin option on unit in cloud-config was not ignored!")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-13 21:56:59 +04:00
|
|
|
func TestCloudConfigUsers(t *testing.T) {
|
2014-03-21 21:35:18 +04:00
|
|
|
contents := `
|
2014-03-13 21:56:59 +04:00
|
|
|
users:
|
|
|
|
- name: elroy
|
|
|
|
passwd: somehash
|
|
|
|
ssh-authorized-keys:
|
|
|
|
- somekey
|
|
|
|
gecos: arbitrary comment
|
|
|
|
homedir: /home/place
|
|
|
|
no-create-home: yes
|
|
|
|
primary-group: things
|
|
|
|
groups:
|
|
|
|
- ping
|
|
|
|
- pong
|
|
|
|
no-user-group: true
|
|
|
|
system: y
|
|
|
|
no-log-init: True
|
2014-03-21 21:35:18 +04:00
|
|
|
`
|
2014-03-13 21:56:59 +04:00
|
|
|
cfg, err := NewCloudConfig(contents)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Encountered unexpected error: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(cfg.Users) != 1 {
|
|
|
|
t.Fatalf("Parsed %d users, expected 1", cfg.Users)
|
|
|
|
}
|
|
|
|
|
|
|
|
user := cfg.Users[0]
|
|
|
|
|
|
|
|
if user.Name != "elroy" {
|
|
|
|
t.Errorf("User name is %q, expected 'elroy'", user.Name)
|
|
|
|
}
|
|
|
|
|
|
|
|
if user.PasswordHash != "somehash" {
|
|
|
|
t.Errorf("User passwd is %q, expected 'somehash'", user.PasswordHash)
|
|
|
|
}
|
|
|
|
|
|
|
|
if keys := user.SSHAuthorizedKeys; len(keys) != 1 {
|
|
|
|
t.Errorf("Parsed %d ssh keys, expected 1", len(keys))
|
|
|
|
} else {
|
|
|
|
key := user.SSHAuthorizedKeys[0]
|
|
|
|
if key != "somekey" {
|
|
|
|
t.Errorf("User SSH key is %q, expected 'somekey'", key)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if user.GECOS != "arbitrary comment" {
|
|
|
|
t.Errorf("Failed to parse gecos field, got %q", user.GECOS)
|
|
|
|
}
|
|
|
|
|
|
|
|
if user.Homedir != "/home/place" {
|
|
|
|
t.Errorf("Failed to parse homedir field, got %q", user.Homedir)
|
|
|
|
}
|
|
|
|
|
|
|
|
if !user.NoCreateHome {
|
|
|
|
t.Errorf("Failed to parse no-create-home field")
|
|
|
|
}
|
|
|
|
|
2014-03-19 19:54:45 +04:00
|
|
|
if user.PrimaryGroup != "things" {
|
2014-03-13 21:56:59 +04:00
|
|
|
t.Errorf("Failed to parse primary-group field, got %q", user.PrimaryGroup)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(user.Groups) != 2 {
|
|
|
|
t.Errorf("Failed to parse 2 goups, got %d", len(user.Groups))
|
|
|
|
} else {
|
|
|
|
if user.Groups[0] != "ping" {
|
|
|
|
t.Errorf("First group was %q, not expected value 'ping'", user.Groups[0])
|
|
|
|
}
|
|
|
|
if user.Groups[1] != "pong" {
|
|
|
|
t.Errorf("First group was %q, not expected value 'pong'", user.Groups[1])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if !user.NoUserGroup {
|
|
|
|
t.Errorf("Failed to parse no-user-group field")
|
|
|
|
}
|
|
|
|
|
|
|
|
if !user.System {
|
|
|
|
t.Errorf("Failed to parse system field")
|
|
|
|
}
|
|
|
|
|
|
|
|
if !user.NoLogInit {
|
|
|
|
t.Errorf("Failed to parse no-log-init field")
|
|
|
|
}
|
|
|
|
}
|