From 0178c5b4b79a8209b1db6bfbb44cf0150135eed5 Mon Sep 17 00:00:00 2001 From: Ken Herner Date: Tue, 25 Jul 2017 16:06:29 -0400 Subject: [PATCH] Added nil check for empty lists in Ignition Config builders Added unit test for Ignition Config testing builders If we pass an empty list down into any of the Ignition Config units (disk, raid, filesystem, file, systemd unit, networkd unit, user, group), the build function for the unit will panic as list will contain nill interfaces (for each empty list passed in). Signed-off-by: Ken Herner --- ignition/resource_ignition_config.go | 24 +++ ignition/resource_ignition_config_test.go | 233 +++++++++++++++++++++- 2 files changed, 255 insertions(+), 2 deletions(-) diff --git a/ignition/resource_ignition_config.go b/ignition/resource_ignition_config.go index e5e09660..87185f14 100644 --- a/ignition/resource_ignition_config.go +++ b/ignition/resource_ignition_config.go @@ -214,6 +214,9 @@ func buildStorage(d *schema.ResourceData, c *cache) (types.Storage, error) { storage := types.Storage{} for _, id := range d.Get("disks").([]interface{}) { + if id == nil { + continue + } d, ok := c.disks[id.(string)] if !ok { return storage, fmt.Errorf("invalid disk %q, unknown disk id", id) @@ -223,6 +226,9 @@ func buildStorage(d *schema.ResourceData, c *cache) (types.Storage, error) { } for _, id := range d.Get("arrays").([]interface{}) { + if id == nil { + continue + } a, ok := c.arrays[id.(string)] if !ok { return storage, fmt.Errorf("invalid raid %q, unknown raid id", id) @@ -232,6 +238,9 @@ func buildStorage(d *schema.ResourceData, c *cache) (types.Storage, error) { } for _, id := range d.Get("filesystems").([]interface{}) { + if id == nil { + continue + } f, ok := c.filesystems[id.(string)] if !ok { return storage, fmt.Errorf("invalid filesystem %q, unknown filesystem id", id) @@ -241,6 +250,9 @@ func buildStorage(d *schema.ResourceData, c *cache) (types.Storage, error) { } for _, id := range d.Get("files").([]interface{}) { + if id == nil { + continue + } f, ok := c.files[id.(string)] if !ok { return storage, fmt.Errorf("invalid file %q, unknown file id", id) @@ -257,6 +269,9 @@ func buildSystemd(d *schema.ResourceData, c *cache) (types.Systemd, error) { systemd := types.Systemd{} for _, id := range d.Get("systemd").([]interface{}) { + if id == nil { + continue + } u, ok := c.systemdUnits[id.(string)] if !ok { return systemd, fmt.Errorf("invalid systemd unit %q, unknown systemd unit id", id) @@ -273,6 +288,9 @@ func buildNetworkd(d *schema.ResourceData, c *cache) (types.Networkd, error) { networkd := types.Networkd{} for _, id := range d.Get("networkd").([]interface{}) { + if id == nil { + continue + } u, ok := c.networkdUnits[id.(string)] if !ok { return networkd, fmt.Errorf("invalid networkd unit %q, unknown networkd unit id", id) @@ -288,6 +306,9 @@ func buildPasswd(d *schema.ResourceData, c *cache) (types.Passwd, error) { passwd := types.Passwd{} for _, id := range d.Get("users").([]interface{}) { + if id == nil { + continue + } u, ok := c.users[id.(string)] if !ok { return passwd, fmt.Errorf("invalid user %q, unknown user id", id) @@ -297,6 +318,9 @@ func buildPasswd(d *schema.ResourceData, c *cache) (types.Passwd, error) { } for _, id := range d.Get("groups").([]interface{}) { + if id == nil { + continue + } g, ok := c.groups[id.(string)] if !ok { return passwd, fmt.Errorf("invalid group %q, unknown group id", id) diff --git a/ignition/resource_ignition_config_test.go b/ignition/resource_ignition_config_test.go index ce7574a5..e47b0473 100644 --- a/ignition/resource_ignition_config_test.go +++ b/ignition/resource_ignition_config_test.go @@ -11,7 +11,7 @@ import ( "github.com/hashicorp/terraform/terraform" ) -func TestIngnitionFileReplace(t *testing.T) { +func TestIgnitionFileReplace(t *testing.T) { testIgnition(t, ` data "ignition_config" "test" { replace { @@ -37,7 +37,7 @@ func TestIngnitionFileReplace(t *testing.T) { }) } -func TestIngnitionFileAppend(t *testing.T) { +func TestIgnitionFileAppend(t *testing.T) { testIgnition(t, ` data "ignition_config" "test" { append { @@ -122,6 +122,235 @@ func TestIngnitionFileAppendNoVerification(t *testing.T) { }) } +func TestIgnitionConfigDisks(t *testing.T) { + testIgnition(t, ` + variable "ignition_disk_ids" { + type = "list" + default = [""] + } + + data "ignition_disk" "test" { + device = "/dev/sda" + partition { + start = 2048 + size = 20480 + } + } + + data "ignition_config" "test" { + disks = [ + "${data.ignition_disk.test.id}", + "${var.ignition_disk_ids}", + ] + } + `, func(c *types.Config) error { + f := c.Storage.Disks[0] + if f.Device != "/dev/sda" { + return fmt.Errorf("device, found %q", f.Device) + } + return nil + }) +} + +func TestIgnitionConfigArrays(t *testing.T) { + testIgnition(t, ` + variable "ignition_array_ids" { + type = "list" + default = [""] + } + + data "ignition_raid" "md" { + name = "data" + level = "stripe" + devices = [ + "/dev/disk/by-partlabel/raid.1.1", + "/dev/disk/by-partlabel/raid.1.2" + ] + } + + data "ignition_config" "test" { + arrays = [ + "${data.ignition_raid.md.id}", + "${var.ignition_array_ids}" + ] + } + `, func(c *types.Config) error { + f := c.Storage.Arrays[0] + if f.Name != "data" { + return fmt.Errorf("device, found %q", f.Name) + } + return nil + }) +} + +func TestIgnitionConfigFilesystems(t *testing.T) { + testIgnition(t, ` + variable "ignition_filesystem_ids" { + type = "list" + default = [""] + } + + data "ignition_filesystem" "test" { + name = "test" + mount = { + device = "/dev/sda" + format = "ext4" + } + } + + data "ignition_config" "test" { + filesystems = [ + "${data.ignition_filesystem.test.id}", + "${var.ignition_filesystem_ids}", + ] + } + `, func(c *types.Config) error { + f := c.Storage.Filesystems[0] + if f.Name != "test" { + return fmt.Errorf("device, found %q", f.Name) + } + return nil + }) +} + +func TestIgnitionConfigFiles(t *testing.T) { + testIgnition(t, ` + variable "ignition_file_ids" { + type = "list" + default = [""] + } + + data "ignition_file" "test" { + filesystem = "foo" + path = "/hello.text" + content { + content = "Hello World!" + } + } + + data "ignition_config" "test" { + files = [ + "${data.ignition_file.test.id}", + "${var.ignition_file_ids}", + ] + } + `, func(c *types.Config) error { + f := c.Storage.Files[0] + if f.Filesystem != "foo" { + return fmt.Errorf("device, found %q", f.Filesystem) + } + return nil + }) +} + +func TestIgnitionConfigSystemd(t *testing.T) { + testIgnition(t, ` + variable "ignition_systemd_ids" { + type = "list" + default = [""] + } + + data "ignition_systemd_unit" "test" { + name = "example.service" + content = "[Service]\nType=oneshot\nExecStart=/usr/bin/echo Hello World\n\n[Install]\nWantedBy=multi-user.target" + } + + data "ignition_config" "test" { + systemd = [ + "${data.ignition_systemd_unit.test.id}", + "${var.ignition_systemd_ids}", + ] + } + `, func(c *types.Config) error { + f := c.Systemd.Units[0] + if f.Name != "example.service" { + return fmt.Errorf("device, found %q", f.Name) + } + return nil + }) +} + +func TestIgnitionConfigNetworkd(t *testing.T) { + testIgnition(t, ` + variable "ignition_networkd_ids" { + type = "list" + default = [""] + } + + data "ignition_networkd_unit" "test" { + name = "00-eth0.network" + content = "[Match]\nName=eth0\n\n[Network]\nAddress=10.0.1.7" + } + + data "ignition_config" "test" { + networkd = [ + "${data.ignition_networkd_unit.test.id}", + "${var.ignition_networkd_ids}", + ] + } + `, func(c *types.Config) error { + f := c.Networkd.Units[0] + if f.Name != "00-eth0.network" { + return fmt.Errorf("device, found %q", f.Name) + } + return nil + }) +} + +func TestIgnitionConfigUsers(t *testing.T) { + testIgnition(t, ` + variable "ignition_user_ids" { + type = "list" + default = [""] + } + + data "ignition_user" "test" { + name = "foo" + home_dir = "/home/foo/" + shell = "/bin/bash" + } + + data "ignition_config" "test" { + users = [ + "${data.ignition_user.test.id}", + "${var.ignition_user_ids}", + ] + } + `, func(c *types.Config) error { + f := c.Passwd.Users[0] + if f.Name != "foo" { + return fmt.Errorf("device, found %q", f.Name) + } + return nil + }) +} + +func TestIgnitionConfigGroupss(t *testing.T) { + testIgnition(t, ` + variable "ignition_group_ids" { + type = "list" + default = [""] + } + + data "ignition_group" "test" { + name = "test" + } + + data "ignition_config" "test" { + groups = [ + "${data.ignition_group.test.id}", + "${var.ignition_group_ids}", + ] + } + `, func(c *types.Config) error { + f := c.Passwd.Groups[0] + if f.Name != "test" { + return fmt.Errorf("device, found %q", f.Name) + } + return nil + }) +} + func testIgnitionError(t *testing.T, input string, expectedErr *regexp.Regexp) { resource.Test(t, resource.TestCase{ IsUnitTest: true,