yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/openstack/vpc.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 openstack
    16  
    17  import (
    18  	"fmt"
    19  	"net/url"
    20  	"time"
    21  
    22  	"yunion.io/x/jsonutils"
    23  	"yunion.io/x/pkg/errors"
    24  
    25  	api "yunion.io/x/cloudmux/pkg/apis/compute"
    26  	"yunion.io/x/cloudmux/pkg/cloudprovider"
    27  	"yunion.io/x/cloudmux/pkg/multicloud"
    28  )
    29  
    30  const (
    31  	VPC_STATUS_ACTIVE = "ACTIVE"
    32  	VPC_STATUS_DOWN   = "DOWN"
    33  	VPC_STATUS_BUILD  = "BUILD"
    34  	VPC_STATUS_ERROR  = "ERROR"
    35  )
    36  
    37  type SVpc struct {
    38  	multicloud.SVpc
    39  	OpenStackTags
    40  	region *SRegion
    41  
    42  	AdminStateUp          bool
    43  	AvailabilityZoneHints []string
    44  	AvailabilityZones     []string
    45  	CreatedAt             time.Time
    46  	DnsDomain             string
    47  	Id                    string
    48  	Ipv4AddressScope      string
    49  	Ipv6AddressScope      string
    50  	L2Adjacency           bool
    51  	Mtu                   int
    52  	Name                  string
    53  	PortSecurityEnabled   bool
    54  	ProjectID             string
    55  	QosPolicyID           string
    56  	RevisionNumber        int
    57  	External              bool `json:"router:external"`
    58  	Shared                bool
    59  	Status                string
    60  	Subnets               []string
    61  	TenantID              string
    62  	UpdatedAt             time.Time
    63  	VlanTransparent       bool
    64  	Fescription           string
    65  	IsDefault             bool
    66  	NetworkType           string `json:"provider:network_type"` // flat, vlan, vxlan, or gre ...
    67  	PhysicalNetwork       string `json:"provider:physical_network"`
    68  	SegmentationId        string `json:"provider:segmentation_id"`
    69  }
    70  
    71  func (vpc *SVpc) GetId() string {
    72  	return vpc.Id
    73  }
    74  
    75  func (vpc *SVpc) GetName() string {
    76  	if len(vpc.Name) > 0 {
    77  		return vpc.Name
    78  	}
    79  	return vpc.Id
    80  }
    81  
    82  func (vpc *SVpc) GetGlobalId() string {
    83  	return vpc.Id
    84  }
    85  
    86  func (vpc *SVpc) IsEmulated() bool {
    87  	return false
    88  }
    89  
    90  func (vpc *SVpc) GetIsDefault() bool {
    91  	return vpc.IsDefault
    92  }
    93  
    94  func (vpc *SVpc) GetCidrBlock() string {
    95  	return ""
    96  }
    97  
    98  func (vpc *SVpc) GetStatus() string {
    99  	switch vpc.Status {
   100  	case VPC_STATUS_ACTIVE:
   101  		return api.VPC_STATUS_AVAILABLE
   102  	case VPC_STATUS_BUILD, VPC_STATUS_DOWN:
   103  		return api.VPC_STATUS_PENDING
   104  	case VPC_STATUS_ERROR:
   105  		return api.VPC_STATUS_FAILED
   106  	default:
   107  		return api.VPC_STATUS_UNKNOWN
   108  	}
   109  }
   110  
   111  func (vpc *SVpc) Delete() error {
   112  	return vpc.region.DeleteVpc(vpc.Id)
   113  }
   114  
   115  func (region *SRegion) DeleteVpc(vpcId string) error {
   116  	resource := fmt.Sprintf("/v2.0/networks/%s", vpcId)
   117  	_, err := region.vpcDelete(resource)
   118  	return err
   119  }
   120  
   121  func (vpc *SVpc) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) {
   122  	err := vpc.region.client.fetchProjects()
   123  	if err != nil {
   124  		return nil, errors.Wrap(err, "fetchProjects")
   125  	}
   126  	iSecgroups := []cloudprovider.ICloudSecurityGroup{}
   127  	for _, project := range vpc.region.client.projects {
   128  		secgroups, err := vpc.region.GetSecurityGroups(project.Id, "")
   129  		if err != nil {
   130  			return nil, errors.Wrapf(err, "GetSecurityGroups(%s)", project.Id)
   131  		}
   132  		for i := 0; i < len(secgroups); i++ {
   133  			secgroups[i].region = vpc.region
   134  			iSecgroups = append(iSecgroups, &secgroups[i])
   135  		}
   136  	}
   137  	return iSecgroups, nil
   138  }
   139  
   140  func (vpc *SVpc) GetIRouteTables() ([]cloudprovider.ICloudRouteTable, error) {
   141  	if vpc.PhysicalNetwork == "public" {
   142  		return []cloudprovider.ICloudRouteTable{}, nil
   143  	}
   144  	err := vpc.region.fetchrouters()
   145  	if err != nil {
   146  		return nil, errors.Wrap(err, "vpc.region.fetchrouters()")
   147  	}
   148  	routeTables := []SRouteTable{}
   149  	for index, router := range vpc.region.routers {
   150  		if len(router.Routes) < 1 {
   151  			continue
   152  		}
   153  		for _, port := range router.ports {
   154  			if port.NetworkID == vpc.GetId() {
   155  				routeTable := SRouteTable{}
   156  				routeTable.entries = router.Routes
   157  				routeTable.router = &vpc.region.routers[index]
   158  				routeTable.vpc = vpc
   159  				routeTables = append(routeTables, routeTable)
   160  				break
   161  			}
   162  		}
   163  	}
   164  	ret := []cloudprovider.ICloudRouteTable{}
   165  	for i := range routeTables {
   166  		ret = append(ret, &routeTables[i])
   167  	}
   168  	return ret, nil
   169  }
   170  
   171  func (self *SVpc) GetIRouteTableById(routeTableId string) (cloudprovider.ICloudRouteTable, error) {
   172  	return nil, cloudprovider.ErrNotSupported
   173  }
   174  
   175  func (vpc *SVpc) GetIWireById(wireId string) (cloudprovider.ICloudWire, error) {
   176  	iwires, err := vpc.GetIWires()
   177  	if err != nil {
   178  		return nil, errors.Wrap(err, "GetIWires")
   179  	}
   180  	for i := range iwires {
   181  		if iwires[i].GetGlobalId() == wireId {
   182  			return iwires[i], nil
   183  		}
   184  	}
   185  	return nil, cloudprovider.ErrNotFound
   186  }
   187  
   188  func (vpc *SVpc) GetIWires() ([]cloudprovider.ICloudWire, error) {
   189  	return []cloudprovider.ICloudWire{&SWire{vpc: vpc}}, nil
   190  }
   191  
   192  func (vpc *SVpc) GetRegion() cloudprovider.ICloudRegion {
   193  	return vpc.region
   194  }
   195  
   196  func (region *SRegion) GetVpc(vpcId string) (*SVpc, error) {
   197  	vpc := &SVpc{region: region}
   198  	resource := fmt.Sprintf("/v2.0/networks/%s", vpcId)
   199  	resp, err := region.vpcGet(resource)
   200  	if err != nil {
   201  		return nil, errors.Wrapf(err, "vpcGet(%s)", resource)
   202  	}
   203  	err = resp.Unmarshal(vpc, "network")
   204  	if err != nil {
   205  		return nil, errors.Wrap(err, "resp.Unmarshal")
   206  	}
   207  	return vpc, nil
   208  }
   209  
   210  func (region *SRegion) GetVpcs(projectId string) ([]SVpc, error) {
   211  	vpcs := []SVpc{}
   212  	resource := "/v2.0/networks"
   213  	query := url.Values{}
   214  	if len(projectId) > 0 {
   215  		query.Set("tenant_id", projectId)
   216  	}
   217  	for {
   218  		resp, err := region.vpcList(resource, query)
   219  		if err != nil {
   220  			return nil, errors.Wrapf(err, "vpcList.%s", resource)
   221  		}
   222  
   223  		part := struct {
   224  			Networks      []SVpc
   225  			NetworksLinks SNextLinks
   226  		}{}
   227  
   228  		err = resp.Unmarshal(&part)
   229  		if err != nil {
   230  			return nil, errors.Wrap(err, "resp.Unmarshal")
   231  		}
   232  		vpcs = append(vpcs, part.Networks...)
   233  		marker := part.NetworksLinks.GetNextMark()
   234  		if len(marker) == 0 {
   235  			break
   236  		}
   237  		query.Set("marker", marker)
   238  	}
   239  	return vpcs, nil
   240  }
   241  
   242  func (vpc *SVpc) Refresh() error {
   243  	_vpc, err := vpc.region.GetVpc(vpc.Id)
   244  	if err != nil {
   245  		return errors.Wrapf(err, "GetVpc(%s)", vpc.Id)
   246  	}
   247  	return jsonutils.Update(vpc, _vpc)
   248  }
   249  
   250  func (region *SRegion) CreateVpc(name, desc string) (*SVpc, error) {
   251  	params := map[string]map[string]string{
   252  		"network": {
   253  			"name":        name,
   254  			"description": desc,
   255  		},
   256  	}
   257  	resource := "/v2.0/networks"
   258  	resp, err := region.vpcPost(resource, params)
   259  	if err != nil {
   260  		return nil, errors.Wrap(err, "vpcPost")
   261  	}
   262  	vpc := &SVpc{region: region}
   263  	err = resp.Unmarshal(vpc, "network")
   264  	if err != nil {
   265  		return nil, errors.Wrap(err, "resp.Unmarshal")
   266  	}
   267  	return vpc, nil
   268  }