From aaf91033309a87c0de1fb7e81bac12ae26fb9dd4 Mon Sep 17 00:00:00 2001 From: Joshua Foster Date: Wed, 17 Jun 2020 01:36:55 -0400 Subject: [PATCH 1/4] use the ip_wait_address range to determine the default for the http server IP --- builder/vsphere/common/step_http_ip_discover.go | 9 +++++---- builder/vsphere/common/step_wait_for_ip.go | 8 ++++++-- builder/vsphere/iso/builder.go | 3 ++- .../builder/vsphere/common/WaitIpConfig-not-required.mdx | 4 ++-- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/builder/vsphere/common/step_http_ip_discover.go b/builder/vsphere/common/step_http_ip_discover.go index 627fbe52b..04fe4f775 100644 --- a/builder/vsphere/common/step_http_ip_discover.go +++ b/builder/vsphere/common/step_http_ip_discover.go @@ -12,11 +12,12 @@ import ( // which guests use to reach the vm host // To make sure the IP is set before boot command and http server steps type StepHTTPIPDiscover struct { - HTTPIP string + HTTPIP string + Network *net.IPNet } func (s *StepHTTPIPDiscover) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { - ip, err := getHostIP(s.HTTPIP) + ip, err := getHostIP(s.HTTPIP, s.Network) if err != nil { state.Put("error", err) return multistep.ActionHalt @@ -28,7 +29,7 @@ func (s *StepHTTPIPDiscover) Run(ctx context.Context, state multistep.StateBag) func (s *StepHTTPIPDiscover) Cleanup(state multistep.StateBag) {} -func getHostIP(s string) (string, error) { +func getHostIP(s string, network *net.IPNet) (string, error) { if s != "" { if net.ParseIP(s) != nil { return s, nil @@ -45,7 +46,7 @@ func getHostIP(s string) (string, error) { for _, a := range addrs { ipnet, ok := a.(*net.IPNet) if ok && !ipnet.IP.IsLoopback() { - if ipnet.IP.To4() != nil { + if network.Contains(ipnet.IP) { return ipnet.IP.String(), nil } } diff --git a/builder/vsphere/common/step_wait_for_ip.go b/builder/vsphere/common/step_wait_for_ip.go index 3d1617f01..3c05916b3 100644 --- a/builder/vsphere/common/step_wait_for_ip.go +++ b/builder/vsphere/common/step_wait_for_ip.go @@ -32,8 +32,8 @@ type WaitIpConfig struct { // this network range. Defaults to "0.0.0.0/0" for any ipv4 address. Examples include: // // * empty string ("") - remove all filters - // * "0:0:0:0:0:0:0:0/0" - allow only ipv6 addresses - // * "192.168.1.0/24 - only allow ipv4 addresses from 192.168.1.1 to 192.168.1.254 + // * `0:0:0:0:0:0:0:0/0` - allow only ipv6 addresses + // * `192.168.1.0/24` - only allow ipv4 addresses from 192.168.1.1 to 192.168.1.254 WaitAddress *string `mapstructure:"ip_wait_address"` ipnet *net.IPNet @@ -69,6 +69,10 @@ func (c *WaitIpConfig) Prepare() []error { return errs } +func (c *WaitIpConfig) GetIPNet() *net.IPNet { + return c.ipnet +} + func (s *StepWaitForIp) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) vm := state.Get("vm").(*driver.VirtualMachine) diff --git a/builder/vsphere/iso/builder.go b/builder/vsphere/iso/builder.go index 2c224b642..f755f2367 100644 --- a/builder/vsphere/iso/builder.go +++ b/builder/vsphere/iso/builder.go @@ -91,7 +91,8 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack SetHostForDatastoreUploads: b.config.SetHostForDatastoreUploads, }, &common.StepHTTPIPDiscover{ - HTTPIP: b.config.BootConfig.HTTPIP, + HTTPIP: b.config.BootConfig.HTTPIP, + Network: b.config.WaitIpConfig.GetIPNet(), }, &packerCommon.StepHTTPServer{ HTTPDir: b.config.HTTPDir, diff --git a/website/pages/partials/builder/vsphere/common/WaitIpConfig-not-required.mdx b/website/pages/partials/builder/vsphere/common/WaitIpConfig-not-required.mdx index 09da727a7..34cdeb1c1 100644 --- a/website/pages/partials/builder/vsphere/common/WaitIpConfig-not-required.mdx +++ b/website/pages/partials/builder/vsphere/common/WaitIpConfig-not-required.mdx @@ -16,6 +16,6 @@ this network range. Defaults to "0.0.0.0/0" for any ipv4 address. Examples include: * empty string ("") - remove all filters - * "0:0:0:0:0:0:0:0/0" - allow only ipv6 addresses - * "192.168.1.0/24 - only allow ipv4 addresses from 192.168.1.1 to 192.168.1.254 + * `0:0:0:0:0:0:0:0/0` - allow only ipv6 addresses + * `192.168.1.0/24` - only allow ipv4 addresses from 192.168.1.1 to 192.168.1.254 \ No newline at end of file From 7fc2ea8422e492af5e6204d1f685c1c346dca4b3 Mon Sep 17 00:00:00 2001 From: Joshua Foster Date: Wed, 17 Jun 2020 01:46:30 -0400 Subject: [PATCH 2/4] add a fallback to an ipv4 address if the the range can't find one --- builder/vsphere/common/step_http_ip_discover.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/builder/vsphere/common/step_http_ip_discover.go b/builder/vsphere/common/step_http_ip_discover.go index 04fe4f775..363c9d472 100644 --- a/builder/vsphere/common/step_http_ip_discover.go +++ b/builder/vsphere/common/step_http_ip_discover.go @@ -43,6 +43,7 @@ func getHostIP(s string, network *net.IPNet) (string, error) { return "", err } + // look for an IP that is contained in the ip_wait_address range for _, a := range addrs { ipnet, ok := a.(*net.IPNet) if ok && !ipnet.IP.IsLoopback() { @@ -51,5 +52,15 @@ func getHostIP(s string, network *net.IPNet) (string, error) { } } } + + // fallback to an ipv4 address if an IP is not found in the range + for _, a := range addrs { + ipnet, ok := a.(*net.IPNet) + if ok && !ipnet.IP.IsLoopback() { + if ipnet.IP.To4() != nil { + return ipnet.IP.String(), nil + } + } + } return "", fmt.Errorf("IP not found") } From fb159e706060359717feb844cb4c6f01dde68bd0 Mon Sep 17 00:00:00 2001 From: Joshua Foster Date: Wed, 17 Jun 2020 11:40:39 -0400 Subject: [PATCH 3/4] add test cases for Network --- .../vsphere/common/step_http_ip_discover.go | 12 +++--- .../common/step_http_ip_discover_test.go | 39 +++++++++++++++++++ 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/builder/vsphere/common/step_http_ip_discover.go b/builder/vsphere/common/step_http_ip_discover.go index 363c9d472..0168ddf1b 100644 --- a/builder/vsphere/common/step_http_ip_discover.go +++ b/builder/vsphere/common/step_http_ip_discover.go @@ -44,11 +44,13 @@ func getHostIP(s string, network *net.IPNet) (string, error) { } // look for an IP that is contained in the ip_wait_address range - for _, a := range addrs { - ipnet, ok := a.(*net.IPNet) - if ok && !ipnet.IP.IsLoopback() { - if network.Contains(ipnet.IP) { - return ipnet.IP.String(), nil + if network != nil { + for _, a := range addrs { + ipnet, ok := a.(*net.IPNet) + if ok && !ipnet.IP.IsLoopback() { + if network.Contains(ipnet.IP) { + return ipnet.IP.String(), nil + } } } } diff --git a/builder/vsphere/common/step_http_ip_discover_test.go b/builder/vsphere/common/step_http_ip_discover_test.go index fd4480daa..9ed6cbb22 100644 --- a/builder/vsphere/common/step_http_ip_discover_test.go +++ b/builder/vsphere/common/step_http_ip_discover_test.go @@ -2,6 +2,7 @@ package common import ( "context" + "net" "testing" "github.com/hashicorp/packer/helper/multistep" @@ -41,4 +42,42 @@ func TestStepHTTPIPDiscover_Run(t *testing.T) { if httpIp != ip { t.Fatalf("bad: Http ip is %s but was supposed to be %s", httpIp, ip) } + + _, ipNet, err := net.ParseCIDR("0.0.0.0/24") + if err != nil { + t.Fatal("error getting ipNet", err) + } + step = new(StepHTTPIPDiscover) + step.Network = ipNet + + // without setting HTTPIP with Network + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { + t.Fatalf("bad action: %#v", action) + } + if _, ok := state.GetOk("error"); ok { + t.Fatal("should NOT have error") + } + _, ok = state.GetOk("http_ip") + if !ok { + t.Fatal("should have http_ip") + } + + // setting HTTPIP with Network + step = &StepHTTPIPDiscover{ + HTTPIP: ip, + Network: ipNet, + } + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { + t.Fatalf("bad action: %#v", action) + } + if _, ok := state.GetOk("error"); ok { + t.Fatal("should NOT have error") + } + httpIp, ok = state.GetOk("http_ip") + if !ok { + t.Fatal("should have http_ip") + } + if httpIp != ip { + t.Fatalf("bad: Http ip is %s but was supposed to be %s", httpIp, ip) + } } From dd40c68ff8d08e95ea5b27391eb999b413b1ef6e Mon Sep 17 00:00:00 2001 From: Joshua Foster Date: Wed, 17 Jun 2020 16:00:38 -0400 Subject: [PATCH 4/4] fix default IP address in test to all ipv4 addresses --- builder/vsphere/common/step_http_ip_discover_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/vsphere/common/step_http_ip_discover_test.go b/builder/vsphere/common/step_http_ip_discover_test.go index 9ed6cbb22..a4225774f 100644 --- a/builder/vsphere/common/step_http_ip_discover_test.go +++ b/builder/vsphere/common/step_http_ip_discover_test.go @@ -43,7 +43,7 @@ func TestStepHTTPIPDiscover_Run(t *testing.T) { t.Fatalf("bad: Http ip is %s but was supposed to be %s", httpIp, ip) } - _, ipNet, err := net.ParseCIDR("0.0.0.0/24") + _, ipNet, err := net.ParseCIDR("0.0.0.0/0") if err != nil { t.Fatal("error getting ipNet", err) }