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 }