mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-01 15:07:17 +08:00
Merge pull request #9298 from ioito/hotfix/qx-openstack-network
fix(region): support openstack subnet allocation pools
This commit is contained in:
@@ -37,12 +37,12 @@ func init() {
|
||||
taskman.RegisterTask(NetworkDeleteTask{})
|
||||
}
|
||||
|
||||
func (self *NetworkDeleteTask) taskFailed(ctx context.Context, network *models.SNetwork, reason jsonutils.JSONObject) {
|
||||
log.Errorf("network delete task fail: %s", reason)
|
||||
network.SetStatus(self.UserCred, api.NETWORK_STATUS_DELETE_FAILED, reason.String())
|
||||
db.OpsLog.LogEvent(network, db.ACT_ALLOCATE_FAIL, reason, self.UserCred)
|
||||
logclient.AddActionLogWithStartable(self, network, logclient.ACT_DELETE, reason, self.UserCred, false)
|
||||
self.SetStageFailed(ctx, reason)
|
||||
func (self *NetworkDeleteTask) taskFailed(ctx context.Context, network *models.SNetwork, err error) {
|
||||
log.Errorf("network delete task fail: %v", err)
|
||||
network.SetStatus(self.UserCred, api.NETWORK_STATUS_DELETE_FAILED, err.Error())
|
||||
db.OpsLog.LogEvent(network, db.ACT_ALLOCATE_FAIL, err, self.UserCred)
|
||||
logclient.AddActionLogWithStartable(self, network, logclient.ACT_DELETE, err, self.UserCred, false)
|
||||
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
|
||||
}
|
||||
|
||||
func (self *NetworkDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
|
||||
@@ -55,13 +55,13 @@ func (self *NetworkDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneMod
|
||||
if inet != nil {
|
||||
err = inet.Delete()
|
||||
if err != nil {
|
||||
self.taskFailed(ctx, network, jsonutils.NewString(err.Error()))
|
||||
self.taskFailed(ctx, network, errors.Wrapf(err, "inet.Delete"))
|
||||
return
|
||||
}
|
||||
} else if errors.Cause(err) == cloudprovider.ErrNotFound {
|
||||
// already deleted, do nothing
|
||||
} else {
|
||||
self.taskFailed(ctx, network, jsonutils.NewString(err.Error()))
|
||||
self.taskFailed(ctx, network, errors.Wrapf(err, "network.GetINetwork"))
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -215,8 +215,11 @@ func (eip *SEipAddress) GetINetworkId() string {
|
||||
return ""
|
||||
}
|
||||
for _, network := range networks {
|
||||
if network.Contains(eip.FloatingIPAddress) {
|
||||
return network.Id
|
||||
for _, pool := range network.AllocationPools {
|
||||
if pool.Contains(eip.FloatingIPAddress) {
|
||||
network.AllocationPools = []AllocationPool{pool}
|
||||
return network.GetGlobalId()
|
||||
}
|
||||
}
|
||||
}
|
||||
log.Errorf("failed to find eip %s(%s) networkId", eip.FloatingIPAddress, eip.FloatingNetworkId)
|
||||
@@ -244,6 +247,7 @@ func (eip *SEipAddress) GetProjectId() string {
|
||||
}
|
||||
|
||||
func (region *SRegion) CreateEip(vpcId, networkId, ip string, projectId string) (*SEipAddress, error) {
|
||||
_, networkId = getNetworkId(networkId)
|
||||
params := map[string]map[string]string{
|
||||
"floatingip": map[string]string{
|
||||
"floating_network_id": vpcId,
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/netutils"
|
||||
"yunion.io/x/pkg/util/regutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
@@ -94,7 +95,15 @@ func (nic *SInstancePort) GetINetwork() cloudprovider.ICloudNetwork {
|
||||
log.Errorf("failed to found network by %s error: %v", nic.FixedIps[i].SubnetId, err)
|
||||
return nil
|
||||
}
|
||||
return network
|
||||
for _, pool := range network.AllocationPools {
|
||||
start, _ := netutils.NewIPV4Addr(pool.Start)
|
||||
end, _ := netutils.NewIPV4Addr(pool.End)
|
||||
ipPool := netutils.NewIPV4AddrRange(start, end)
|
||||
ip, _ := netutils.NewIPV4Addr(nic.FixedIps[i].IpAddress)
|
||||
ipPool.Contains(ip)
|
||||
network.AllocationPools = []AllocationPool{pool}
|
||||
return network
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -17,6 +17,7 @@ package openstack
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
@@ -31,8 +32,38 @@ import (
|
||||
)
|
||||
|
||||
type AllocationPool struct {
|
||||
Start string
|
||||
End string
|
||||
Start string `json:"start"`
|
||||
End string `json:"end"`
|
||||
}
|
||||
|
||||
func (p AllocationPool) IsValid() bool {
|
||||
for _, ip := range []string{p.Start, p.End} {
|
||||
_, err := netutils.NewIPV4Addr(ip)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (p AllocationPool) Equals(s AllocationPool) bool {
|
||||
return p.Start == s.Start && p.End == s.End
|
||||
}
|
||||
|
||||
func (p AllocationPool) Contains(ip string) bool {
|
||||
start, err := netutils.NewIPV4Addr(p.Start)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
end, err := netutils.NewIPV4Addr(p.End)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
addr, err := netutils.NewIPV4Addr(ip)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return netutils.NewIPV4AddrRange(start, end).Contains(addr)
|
||||
}
|
||||
|
||||
type SNextLinks []SNextLink
|
||||
@@ -102,6 +133,9 @@ func (network *SNetwork) GetName() string {
|
||||
}
|
||||
|
||||
func (network *SNetwork) GetGlobalId() string {
|
||||
if len(network.AllocationPools) > 0 {
|
||||
return fmt.Sprintf("%s|%s-%s", network.Id, network.AllocationPools[0].Start, network.AllocationPools[0].End)
|
||||
}
|
||||
return network.Id
|
||||
}
|
||||
|
||||
@@ -114,7 +148,29 @@ func (network *SNetwork) GetStatus() string {
|
||||
}
|
||||
|
||||
func (network *SNetwork) Delete() error {
|
||||
return network.wire.zone.region.DeleteNetwork(network.Id)
|
||||
nw, err := network.wire.zone.region.GetNetwork(network.Id)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "GetNetwork(%s)", network.Id)
|
||||
}
|
||||
if len(nw.AllocationPools) <= 1 || len(network.AllocationPools) == 0 {
|
||||
return network.wire.zone.region.DeleteNetwork(network.Id)
|
||||
}
|
||||
pools := []AllocationPool{}
|
||||
for i := range nw.AllocationPools {
|
||||
if nw.AllocationPools[i].Equals(network.AllocationPools[0]) {
|
||||
continue
|
||||
}
|
||||
pools = append(pools, nw.AllocationPools[i])
|
||||
}
|
||||
|
||||
params := map[string]interface{}{
|
||||
"subnet": map[string]interface{}{
|
||||
"allocation_pools": pools,
|
||||
},
|
||||
}
|
||||
resource := fmt.Sprintf("/v2.0/subnets/%s", network.Id)
|
||||
_, err = network.wire.zone.region.vpcUpdate(resource, jsonutils.Marshal(params))
|
||||
return err
|
||||
}
|
||||
|
||||
func (region *SRegion) DeleteNetwork(networkId string) error {
|
||||
@@ -156,11 +212,12 @@ func (network *SNetwork) GetIPRange() netutils.IPV4AddrRange {
|
||||
}
|
||||
|
||||
func (network *SNetwork) Contains(ipAddr string) bool {
|
||||
ip, err := netutils.NewIPV4Addr(ipAddr)
|
||||
if err != nil {
|
||||
return false
|
||||
for _, pool := range network.AllocationPools {
|
||||
if pool.Contains(ipAddr) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return network.GetIPRange().Contains(ip)
|
||||
return false
|
||||
}
|
||||
|
||||
func (network *SNetwork) GetIpMask() int8 {
|
||||
@@ -183,7 +240,21 @@ func (network *SNetwork) GetServerType() string {
|
||||
return api.NETWORK_TYPE_GUEST
|
||||
}
|
||||
|
||||
func getNetworkId(networkId string) (AllocationPool, string) {
|
||||
pool := AllocationPool{}
|
||||
if !strings.Contains(networkId, "|") {
|
||||
return pool, networkId
|
||||
}
|
||||
info := strings.Split(networkId, "|")
|
||||
networkId = info[0]
|
||||
ipInfo := strings.Split(info[1], "-")
|
||||
pool.Start, pool.End = ipInfo[0], ipInfo[1]
|
||||
return pool, networkId
|
||||
}
|
||||
|
||||
func (region *SRegion) GetNetwork(networkId string) (*SNetwork, error) {
|
||||
var pool AllocationPool
|
||||
pool, networkId = getNetworkId(networkId)
|
||||
resource := fmt.Sprintf("/v2.0/subnets/%s", networkId)
|
||||
resp, err := region.vpcGet(resource)
|
||||
if err != nil {
|
||||
@@ -194,7 +265,16 @@ func (region *SRegion) GetNetwork(networkId string) (*SNetwork, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return network, nil
|
||||
if len(pool.Start) == 0 && len(pool.End) == 0 {
|
||||
return network, nil
|
||||
}
|
||||
for _, _pool := range network.AllocationPools {
|
||||
if _pool.Equals(pool) {
|
||||
network.AllocationPools = []AllocationPool{pool}
|
||||
return network, nil
|
||||
}
|
||||
}
|
||||
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "%s", networkId)
|
||||
}
|
||||
|
||||
func (region *SRegion) GetNetworks(vpcId string) ([]SNetwork, error) {
|
||||
|
||||
@@ -39,6 +39,8 @@ type ExtraDhcpOpt struct {
|
||||
}
|
||||
|
||||
type SFixedIP struct {
|
||||
port *SPort
|
||||
|
||||
IpAddress string
|
||||
SubnetID string
|
||||
}
|
||||
@@ -52,7 +54,17 @@ func (fixip *SFixedIP) GetIP() string {
|
||||
}
|
||||
|
||||
func (fixip *SFixedIP) GetINetworkId() string {
|
||||
return fixip.SubnetID
|
||||
network, err := fixip.port.region.GetNetwork(fixip.SubnetID)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
for _, pool := range network.AllocationPools {
|
||||
if pool.Contains(fixip.IpAddress) {
|
||||
network.AllocationPools = []AllocationPool{pool}
|
||||
return network.GetGlobalId()
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (fixip *SFixedIP) IsPrimary() bool {
|
||||
@@ -137,6 +149,7 @@ func (port *SPort) GetStatus() string {
|
||||
func (port *SPort) GetICloudInterfaceAddresses() ([]cloudprovider.ICloudInterfaceAddress, error) {
|
||||
address := []cloudprovider.ICloudInterfaceAddress{}
|
||||
for i := 0; i < len(port.FixedIps); i++ {
|
||||
port.FixedIps[i].port = port
|
||||
address = append(address, &port.FixedIps[i])
|
||||
}
|
||||
return address, nil
|
||||
|
||||
@@ -87,14 +87,25 @@ func (wire *SWire) GetINetworkById(netid string) (cloudprovider.ICloudNetwork, e
|
||||
return networks[i], nil
|
||||
}
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
return nil, errors.Wrapf(cloudprovider.ErrNotFound, netid)
|
||||
}
|
||||
|
||||
func (wire *SWire) GetINetworks() ([]cloudprovider.ICloudNetwork, error) {
|
||||
networks, err := wire.vpc.region.GetNetworks(wire.vpc.Id)
|
||||
_networks, err := wire.vpc.region.GetNetworks(wire.vpc.Id)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "GetNetworks(%s)", wire.vpc.Id)
|
||||
}
|
||||
networks := []SNetwork{}
|
||||
for i := range _networks {
|
||||
pools := _networks[i].AllocationPools
|
||||
for j := range pools {
|
||||
if !pools[j].IsValid() {
|
||||
continue
|
||||
}
|
||||
_networks[i].AllocationPools = []AllocationPool{pools[j]}
|
||||
networks = append(networks, _networks[i])
|
||||
}
|
||||
}
|
||||
inetworks := []cloudprovider.ICloudNetwork{}
|
||||
for i := range networks {
|
||||
networks[i].wire = wire
|
||||
|
||||
Reference in New Issue
Block a user