yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/ctyun/network.go (about)

     1  // Copyright 2019 Yunion
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package ctyun
    16  
    17  import (
    18  	"fmt"
    19  	"strconv"
    20  	"time"
    21  
    22  	"yunion.io/x/jsonutils"
    23  	"yunion.io/x/log"
    24  	"yunion.io/x/pkg/errors"
    25  	"yunion.io/x/pkg/util/netutils"
    26  
    27  	api "yunion.io/x/cloudmux/pkg/apis/compute"
    28  	"yunion.io/x/cloudmux/pkg/cloudprovider"
    29  	"yunion.io/x/cloudmux/pkg/multicloud"
    30  	"yunion.io/x/onecloud/pkg/util/rbacutils"
    31  )
    32  
    33  type SNetwork struct {
    34  	multicloud.SResourceBase
    35  	CtyunTags
    36  	vpc  *SVpc
    37  	wire *SWire
    38  
    39  	CIDR            string `json:"cidr"`
    40  	FirstDcn        string `json:"firstDcn"`
    41  	Gateway         string `json:"gateway"`
    42  	Name            string `json:"name"`
    43  	NeutronSubnetID string `json:"neutronSubnetId"`
    44  	RegionID        string `json:"regionId"`
    45  	ResVLANID       string `json:"resVlanId"`
    46  	SecondDcn       string `json:"secondDcn"`
    47  	VLANStatus      string `json:"vlanStatus"`
    48  	VpcID           string `json:"vpcId"`
    49  	ZoneID          string `json:"zoneId"`
    50  	ZoneName        string `json:"zoneName"`
    51  }
    52  
    53  func (self *SNetwork) GetId() string {
    54  	return self.ResVLANID
    55  }
    56  
    57  func (self *SNetwork) GetName() string {
    58  	return self.Name
    59  }
    60  
    61  func (self *SNetwork) GetGlobalId() string {
    62  	return self.GetId()
    63  }
    64  
    65  func (self *SNetwork) GetStatus() string {
    66  	switch self.VLANStatus {
    67  	case "ACTIVE", "UNKNOWN":
    68  		return api.NETWORK_STATUS_AVAILABLE
    69  	case "ERROR":
    70  		return api.NETWORK_STATUS_UNKNOWN
    71  	default:
    72  		return api.NETWORK_STATUS_UNKNOWN
    73  	}
    74  }
    75  
    76  func (self *SNetwork) Refresh() error {
    77  	log.Debugf("network refresh %s", self.GetId())
    78  	new, err := self.wire.region.GetNetwork(self.GetId())
    79  	if err != nil {
    80  		return err
    81  	}
    82  	return jsonutils.Update(self, new)
    83  }
    84  
    85  func (self *SNetwork) IsEmulated() bool {
    86  	return false
    87  }
    88  
    89  func (self *SNetwork) GetProjectId() string {
    90  	return ""
    91  }
    92  
    93  func (self *SNetwork) GetIWire() cloudprovider.ICloudWire {
    94  	return self.wire
    95  }
    96  
    97  func (self *SNetwork) GetIpStart() string {
    98  	pref, _ := netutils.NewIPV4Prefix(self.CIDR)
    99  	startIp := pref.Address.NetAddr(pref.MaskLen) // 0
   100  	startIp = startIp.StepUp()                    // 1
   101  	startIp = startIp.StepUp()                    // 2
   102  	return startIp.String()
   103  }
   104  
   105  func (self *SNetwork) GetIpEnd() string {
   106  	pref, _ := netutils.NewIPV4Prefix(self.CIDR)
   107  	endIp := pref.Address.BroadcastAddr(pref.MaskLen) // 255
   108  	endIp = endIp.StepDown()                          // 254
   109  	endIp = endIp.StepDown()                          // 253
   110  	endIp = endIp.StepDown()                          // 252
   111  	return endIp.String()
   112  }
   113  
   114  func (self *SNetwork) GetIpMask() int8 {
   115  	pref, _ := netutils.NewIPV4Prefix(self.CIDR)
   116  	return pref.MaskLen
   117  }
   118  
   119  func (self *SNetwork) GetGateway() string {
   120  	pref, _ := netutils.NewIPV4Prefix(self.CIDR)
   121  	startIp := pref.Address.NetAddr(pref.MaskLen) // 0
   122  	startIp = startIp.StepUp()                    // 1
   123  	return startIp.String()
   124  }
   125  
   126  func (self *SNetwork) GetServerType() string {
   127  	return api.NETWORK_TYPE_GUEST
   128  }
   129  
   130  func (self *SNetwork) GetIsPublic() bool {
   131  	return true
   132  }
   133  
   134  func (self *SNetwork) GetPublicScope() rbacutils.TRbacScope {
   135  	return rbacutils.ScopeDomain
   136  }
   137  
   138  func (self *SNetwork) Delete() error {
   139  	return self.vpc.region.DeleteNetwork(self.vpc.GetId(), self.GetId())
   140  }
   141  
   142  func (self *SNetwork) GetAllocTimeoutSeconds() int {
   143  	return 120
   144  }
   145  
   146  func (self *SRegion) GetNetwroks(vpcId string) ([]SNetwork, error) {
   147  	querys := map[string]string{
   148  		"regionId": self.GetId(),
   149  	}
   150  	if len(vpcId) > 0 {
   151  		querys["vpcId"] = vpcId
   152  	}
   153  
   154  	networks := make([]SNetwork, 0)
   155  	resp, err := self.client.DoGet("/apiproxy/v3/getSubnets", querys)
   156  	if err != nil {
   157  		return nil, errors.Wrap(err, "SRegion.GetNetwroks.DoGet")
   158  	}
   159  
   160  	err = resp.Unmarshal(&networks, "returnObj")
   161  	if err != nil {
   162  		return nil, errors.Wrap(err, "SRegion.GetNetwroks.Unmarshal")
   163  	}
   164  
   165  	for i := range networks {
   166  		vpc, err := self.GetVpc(networks[i].VpcID)
   167  		if err != nil {
   168  			return nil, errors.Wrap(err, "SRegion.GetNetwork.GetVpc")
   169  		}
   170  		networks[i].vpc = vpc
   171  
   172  		networks[i].wire = &SWire{
   173  			region: self,
   174  			vpc:    vpc,
   175  		}
   176  
   177  		networks[i].wire.addNetwork(&networks[i])
   178  	}
   179  
   180  	return networks, err
   181  }
   182  
   183  func (self *SRegion) getNetwork(subnetId string) (*SNetwork, error) {
   184  	querys := map[string]string{
   185  		"subnetId": subnetId,
   186  		"regionId": self.GetId(),
   187  	}
   188  
   189  	resp, err := self.client.DoGet("/apiproxy/v3/querySubnetDetail", querys)
   190  	if err != nil {
   191  		return nil, errors.Wrap(err, "SRegion.getNetwork.DoGet")
   192  	}
   193  
   194  	network := &SNetwork{}
   195  	err = resp.Unmarshal(network, "returnObj")
   196  	if err != nil {
   197  		return nil, errors.Wrap(err, "SRegion.getNetwork.Unmarshal")
   198  	}
   199  
   200  	return network, nil
   201  }
   202  
   203  func (self *SRegion) GetNetwork(subnetId string) (*SNetwork, error) {
   204  	network, err := self.getNetwork(subnetId)
   205  	if err != nil {
   206  		return nil, errors.Wrap(err, "SRegion.GetNetwork.getNetwork")
   207  	}
   208  
   209  	vpc, err := self.GetVpc(network.VpcID)
   210  	if err != nil {
   211  		return nil, errors.Wrap(err, "SRegion.GetNetwork.GetVpc")
   212  	}
   213  	network.vpc = vpc
   214  
   215  	network.wire = &SWire{
   216  		region: self,
   217  		vpc:    vpc,
   218  	}
   219  
   220  	network.wire.addNetwork(network)
   221  	return network, err
   222  }
   223  
   224  func (self *SRegion) CreateNetwork(vpcId, zoneId, name, cidr, dhcpEnable string) (*SNetwork, error) {
   225  	gateway, err := getDefaultGateWay(cidr)
   226  	if err != nil {
   227  		return nil, err
   228  	}
   229  
   230  	networkParams := jsonutils.NewDict()
   231  	networkParams.Set("regionId", jsonutils.NewString(self.GetId()))
   232  	networkParams.Set("zoneId", jsonutils.NewString(zoneId))
   233  	networkParams.Set("name", jsonutils.NewString(name))
   234  	networkParams.Set("cidr", jsonutils.NewString(cidr))
   235  	networkParams.Set("gatewayIp", jsonutils.NewString(gateway))
   236  	networkParams.Set("dhcpEnable", jsonutils.NewString(dhcpEnable))
   237  	networkParams.Set("vpcId", jsonutils.NewString(vpcId))
   238  	// DNS地址,如果主机需要访问公网就需要填写该值,不填写就不能使用DNS解析
   239  	// networkParams.Set("primaryDns", jsonutils.NewString(primaryDns))
   240  	// networkParams.Set("secondaryDns", jsonutils.NewString(secondaryDns))
   241  
   242  	params := map[string]jsonutils.JSONObject{
   243  		"jsonStr": networkParams,
   244  	}
   245  
   246  	resp, err := self.client.DoPost("/apiproxy/v3/createSubnet", params)
   247  	if err != nil {
   248  		return nil, errors.Wrap(err, "SRegion.CreateNetwork.DoPost")
   249  	}
   250  
   251  	netId, err := resp.GetString("returnObj", "id")
   252  	if err != nil {
   253  		return nil, errors.Wrap(err, "SRegion.CreateNetwork.GetString")
   254  	}
   255  
   256  	err = cloudprovider.WaitCreated(10*time.Second, 180*time.Second, func() bool {
   257  		network, err := self.getNetwork(netId)
   258  		if err != nil {
   259  			log.Debugf("SRegion.CreateNetwork.getNetwork")
   260  			return false
   261  		}
   262  
   263  		if len(network.VpcID) == 0 {
   264  			return false
   265  		} else {
   266  			return true
   267  		}
   268  	})
   269  	if err != nil {
   270  		return nil, errors.Wrap(err, "SRegion.CreateNetwork.GetVpc")
   271  	}
   272  
   273  	return self.GetNetwork(netId)
   274  }
   275  
   276  func (self *SRegion) DeleteNetwork(vpcId, subnetId string) error {
   277  	params := map[string]jsonutils.JSONObject{
   278  		"regionId": jsonutils.NewString(self.GetId()),
   279  		"vpcId":    jsonutils.NewString(vpcId),
   280  		"subnetId": jsonutils.NewString(subnetId),
   281  	}
   282  
   283  	resp, err := self.client.DoPost("/apiproxy/v3/deleteSubnet", params)
   284  	if err != nil {
   285  		return errors.Wrap(err, "SRegion.DeleteNetwork.DoPost")
   286  	}
   287  
   288  	var statusCode int
   289  	err = resp.Unmarshal(&statusCode, "statusCode")
   290  	if statusCode != 800 {
   291  		return errors.Wrap(fmt.Errorf(strconv.Itoa(statusCode)), "SRegion.DeleteNetwork.Failed")
   292  	}
   293  
   294  	return nil
   295  }