diff --git a/pkg/compute/models/cloudaccounts_test.go b/pkg/compute/models/cloudaccounts_test.go deleted file mode 100644 index c95704cc41..0000000000 --- a/pkg/compute/models/cloudaccounts_test.go +++ /dev/null @@ -1,201 +0,0 @@ -// Copyright 2019 Yunion -// -// 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 models - -import ( - "reflect" - "sort" - "testing" - - "yunion.io/x/pkg/util/netutils" - - api "yunion.io/x/onecloud/pkg/apis/compute" -) - -func TestSCloudaccount_suggestHostNetworks(t *testing.T) { - cases := []struct { - in []string - want []api.CASimpleNetConf - }{ - { - []string{ - "10.168.13.234", - "10.168.13.235", - "10.168.13.233", - "10.168.13.222", - }, - []api.CASimpleNetConf{ - { - GuestIpStart: "10.168.13.222", - GuestIpEnd: "10.168.13.222", - GuestIpMask: 24, - GuestGateway: "10.168.13.1", - }, - { - GuestIpStart: "10.168.13.233", - GuestIpEnd: "10.168.13.235", - GuestIpMask: 24, - GuestGateway: "10.168.13.1", - }, - }, - }, - { - []string{ - "10.168.12.254", - "10.168.43.1", - }, - []api.CASimpleNetConf{ - { - GuestIpStart: "10.168.12.254", - GuestIpEnd: "10.168.12.254", - GuestIpMask: 24, - GuestGateway: "10.168.12.1", - }, - { - GuestIpStart: "10.168.43.1", - GuestIpEnd: "10.168.43.1", - GuestIpMask: 24, - GuestGateway: "10.168.43.1", - }, - }, - }, - { - []string{ - "10.155.50.103", - "10.155.50.101", - "10.155.50.102", - }, - []api.CASimpleNetConf{ - { - GuestIpStart: "10.155.50.101", - GuestIpEnd: "10.155.50.103", - GuestIpMask: 24, - GuestGateway: "10.155.50.1", - }, - }, - }, - } - for _, c := range cases { - ins := make([]netutils.IPV4Addr, len(c.in)) - for i := range ins { - ins[i], _ = netutils.NewIPV4Addr(c.in[i]) - } - out := CloudaccountManager.suggestHostNetworks(ins) - sort.Slice(out, func(i, j int) bool { - if out[i].GuestIpStart == out[j].GuestIpStart { - return out[i].GuestIpEnd < out[j].GuestIpEnd - } - return out[i].GuestIpStart < out[j].GuestIpStart - }) - if !reflect.DeepEqual(out, c.want) { - t.Fatalf("want: %#v\nreal: %#v", c.want, out) - } - } -} - -func TestSCloudaccount_suggestVMNetwors(t *testing.T) { - cases := []struct { - in1 []string - in2 []struct { - startIp string - endIp string - } - want []api.CASimpleNetConf - }{ - { - in1: []string{ - "10.168.222.23", - "10.168.222.26", - "10.168.222.145", - "10.168.222.234", - }, - in2: []struct { - startIp string - endIp string - }{ - {"10.168.222.45", "10.168.222.120"}, - {"10.168.222.200", "10.168.222.230"}, - }, - want: []api.CASimpleNetConf{ - { - GuestIpStart: "10.168.222.1", - GuestIpEnd: "10.168.222.44", - GuestIpMask: 24, - GuestGateway: "10.168.222.1", - }, - { - GuestIpStart: "10.168.222.121", - GuestIpEnd: "10.168.222.199", - GuestIpMask: 24, - GuestGateway: "10.168.222.1", - }, - { - GuestIpStart: "10.168.222.231", - GuestIpEnd: "10.168.222.254", - GuestIpMask: 24, - GuestGateway: "10.168.222.1", - }, - }, - }, - { - in1: []string{ - "10.168.222.23", - "10.168.224.178", - }, - in2: []struct { - startIp string - endIp string - }{ - {"10.168.222.100", "10.168.224.100"}, - }, - want: []api.CASimpleNetConf{ - { - GuestIpStart: "10.168.222.1", - GuestIpEnd: "10.168.222.99", - GuestIpMask: 24, - GuestGateway: "10.168.222.1", - }, - { - GuestIpStart: "10.168.224.101", - GuestIpEnd: "10.168.224.254", - GuestIpMask: 24, - GuestGateway: "10.168.224.1", - }, - }, - }, - } - for _, c := range cases { - ins1 := make([]netutils.IPV4Addr, len(c.in1)) - ins2 := make([]netutils.IPV4AddrRange, len(c.in2)) - for i := range ins1 { - ins1[i], _ = netutils.NewIPV4Addr(c.in1[i]) - } - for i := range ins2 { - ip1, _ := netutils.NewIPV4Addr(c.in2[i].startIp) - ip2, _ := netutils.NewIPV4Addr(c.in2[i].endIp) - ins2[i] = netutils.NewIPV4AddrRange(ip1, ip2) - } - out := CloudaccountManager.suggestVMNetwors(ins1, ins2) - sort.Slice(out, func(i, j int) bool { - if out[i].GuestIpStart == out[j].GuestIpStart { - return out[i].GuestIpEnd < out[j].GuestIpEnd - } - return out[i].GuestIpStart < out[j].GuestIpStart - }) - if !reflect.DeepEqual(out, c.want) { - t.Fatalf("want: %#v\nreal: %#v", c.want, out) - } - } -} diff --git a/pkg/compute/options/options.go b/pkg/compute/options/options.go index 2efb120590..3a126d9164 100644 --- a/pkg/compute/options/options.go +++ b/pkg/compute/options/options.go @@ -17,6 +17,7 @@ package options import ( common_options "yunion.io/x/onecloud/pkg/cloudcommon/options" "yunion.io/x/onecloud/pkg/cloudcommon/pending_delete" + "yunion.io/x/onecloud/pkg/multicloud/esxi" ) type ComputeOptions struct { @@ -153,6 +154,8 @@ type ComputeOptions struct { EnableAutoMergeSecurityGroup bool `help:"Enable auto merge secgroup when sync security group from cloud, default False" default:"false"` DefaultNetworkGatewayAddressEsxi uint32 `help:"Default address for network gateway" default:"1"` + + esxi.VMIPOptions } type SCapabilityOptions struct { diff --git a/pkg/compute/service/service.go b/pkg/compute/service/service.go index d30a562d30..554c88d71d 100644 --- a/pkg/compute/service/service.go +++ b/pkg/compute/service/service.go @@ -44,6 +44,7 @@ import ( _ "yunion.io/x/onecloud/pkg/compute/tasks" "yunion.io/x/onecloud/pkg/controller/autoscaling" "yunion.io/x/onecloud/pkg/httperrors" + "yunion.io/x/onecloud/pkg/multicloud/esxi" _ "yunion.io/x/onecloud/pkg/multicloud/loader" ) @@ -59,6 +60,11 @@ func StartService() { commonOpts.Port = opts.PortV2 } + err := esxi.InitVMIPV4Filter(opts.ReasonableCIDREsxi) + if err != nil { + log.Fatalf("unable to initVMIPV4Filter: %v", err) + } + app_common.InitAuth(commonOpts, func() { log.Infof("Auth complete!!") }) diff --git a/pkg/multicloud/esxi/ip.go b/pkg/multicloud/esxi/ip.go index 603bff4dab..70f510e775 100644 --- a/pkg/multicloud/esxi/ip.go +++ b/pkg/multicloud/esxi/ip.go @@ -17,10 +17,47 @@ package esxi import ( "github.com/vmware/govmomi/vim25/mo" + "yunion.io/x/log" "yunion.io/x/pkg/errors" + "yunion.io/x/pkg/util/netutils" "yunion.io/x/pkg/util/regutils" ) +type VMIPOptions struct { + ReasonableCIDREsxi string `help:"Reasonable CIDR in esxi, such as '10.0.0.0/8'" defautl:""` +} + +type IPV4Range struct { + iprange *netutils.IPV4AddrRange +} + +func (i IPV4Range) Contains(ip string) bool { + ipaddr, err := netutils.NewIPV4Addr(ip) + if err != nil { + log.Errorf("unable to parse ip %q: %v", ip, err) + return false + } + if i.iprange == nil { + return true + } + return i.iprange.Contains(ipaddr) +} + +var vmIPV4Filter IPV4Range + +func InitVMIPV4Filter(cidr string) error { + if len(cidr) == 0 { + return nil + } + prefix, err := netutils.NewIPV4Prefix(cidr) + if err != nil { + return errors.Wrapf(err, "parse cidr %q", cidr) + } + irange := prefix.ToIPRange() + vmIPV4Filter.iprange = &irange + return nil +} + var HOST_PROPS = []string{"name", "config.network", "vm"} var VM_PROPS = []string{"name", "guest.net", "config.template", "summary.config.uuid", "summary.runtime.powerState"} diff --git a/pkg/multicloud/esxi/manager.go b/pkg/multicloud/esxi/manager.go index 64b7d653db..0c81e71105 100644 --- a/pkg/multicloud/esxi/manager.go +++ b/pkg/multicloud/esxi/manager.go @@ -680,14 +680,22 @@ func (cli *SESXiClient) vmIPs(host *mo.HostSystem) ([]SSimpleVM, error) { } guestIps := make([]string, 0) for _, net := range vm.Guest.Net { + if len(net.Network) == 0 { + continue + } for _, ip := range net.IpAddress { - if regutils.MatchIP4Addr(ip) { - ipaddr, _ := netutils.NewIPV4Addr(ip) - if netutils.IsLinkLocal(ipaddr) { - continue - } - guestIps = append(guestIps, ip) + if !regutils.MatchIP4Addr(ip) { + continue } + if !vmIPV4Filter.Contains(ip) { + continue + } + ipaddr, _ := netutils.NewIPV4Addr(ip) + if netutils.IsLinkLocal(ipaddr) { + continue + } + guestIps = append(guestIps, ip) + break } } ret = append(ret, SSimpleVM{vm.Name, guestIps}) diff --git a/pkg/multicloud/esxi/virtualmachine.go b/pkg/multicloud/esxi/virtualmachine.go index c8743260ed..b7e5705089 100644 --- a/pkg/multicloud/esxi/virtualmachine.go +++ b/pkg/multicloud/esxi/virtualmachine.go @@ -763,6 +763,9 @@ func (self *SVirtualMachine) fetchGuestIps() map[string]string { mac := netutils.FormatMacAddr(net.MacAddress) for _, ip := range net.IpAddress { if regutils.MatchIP4Addr(ip) { + if !vmIPV4Filter.Contains(ip) { + continue + } guestIps[mac] = ip break }