yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/zstack/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 zstack 16 17 import ( 18 "fmt" 19 "net/url" 20 21 "yunion.io/x/jsonutils" 22 "yunion.io/x/pkg/util/netutils" 23 24 api "yunion.io/x/cloudmux/pkg/apis/compute" 25 "yunion.io/x/cloudmux/pkg/cloudprovider" 26 "yunion.io/x/cloudmux/pkg/multicloud" 27 "yunion.io/x/onecloud/pkg/util/rbacutils" 28 ) 29 30 type SNetwork struct { 31 multicloud.SResourceBase 32 ZStackTags 33 wire *SWire 34 35 ZStackBasic 36 L3NetworkUUID string `json:"l3NetworkUuid"` 37 StartIP string `json:"startIp"` 38 EndIP string `json:"endIp"` 39 Netmask string `json:"netmask"` 40 Gateway string `json:"gateway"` 41 NetworkCIDR string `json:"networkCidr"` 42 IPVersion int `json:"ipVersion"` 43 PrefixLen int `json:"prefixLen"` 44 ZStackTime 45 } 46 47 type SHostRoute struct { 48 ID int 49 L3NetworkUuid string `json:"l3NetworkUuid"` 50 Prefix string 51 Nexthop string 52 ZStackTime 53 } 54 55 type SL3Network struct { 56 ZStackBasic 57 Type string `json:"type"` 58 ZoneUUID string `json:"zoneUuid"` 59 L2NetworkUUID string `json:"l2NetworkUuid"` 60 State string `json:"state"` 61 System bool `json:"system"` 62 Category bool `json:"category"` 63 IPVersion int `json:"ipVersion"` 64 DNS []string `json:"dns"` 65 Networks []SNetwork `json:"ipRanges"` 66 HostRoute []SHostRoute `json:"hostRoute"` 67 ZStackTime 68 } 69 70 func (region *SRegion) GetNetwork(zoneId, wireId, l3Id, networkId string) (*SNetwork, error) { 71 networks, err := region.GetNetworks(zoneId, wireId, l3Id, networkId) 72 if err != nil { 73 return nil, err 74 } 75 if len(networks) == 1 { 76 if networks[0].UUID == networkId { 77 return &networks[0], nil 78 } 79 return nil, cloudprovider.ErrNotFound 80 } 81 if len(networks) == 0 || len(networkId) == 0 { 82 return nil, cloudprovider.ErrNotFound 83 } 84 return nil, cloudprovider.ErrDuplicateId 85 } 86 87 func (region *SRegion) GetL3Network(l3Id string) (*SL3Network, error) { 88 l3network := &SL3Network{} 89 return l3network, region.client.getResource("l3-networks", l3Id, l3network) 90 } 91 92 func (region *SRegion) GetL3Networks(zoneId string, wireId string, l3Id string) ([]SL3Network, error) { 93 l3Networks := []SL3Network{} 94 params := url.Values{} 95 if len(zoneId) > 0 { 96 params.Add("q", "zone.uuid="+zoneId) 97 } 98 if len(wireId) > 0 { 99 params.Add("q", "l2NetworkUuid="+wireId) 100 } 101 if len(l3Id) > 0 { 102 params.Add("q", "uuid="+l3Id) 103 } 104 return l3Networks, region.client.listAll("l3-networks", params, &l3Networks) 105 } 106 107 func (region *SRegion) GetNetworks(zoneId string, wireId string, l3Id string, networkId string) ([]SNetwork, error) { 108 l3Networks, err := region.GetL3Networks(zoneId, wireId, l3Id) 109 if err != nil { 110 return nil, err 111 } 112 networks := []SNetwork{} 113 for i := 0; i < len(l3Networks); i++ { 114 for j := 0; j < len(l3Networks[i].Networks); j++ { 115 if len(networkId) == 0 || l3Networks[i].Networks[j].UUID == networkId { 116 networks = append(networks, l3Networks[i].Networks[j]) 117 } 118 } 119 } 120 return networks, nil 121 } 122 123 func (network *SNetwork) GetId() string { 124 return network.UUID 125 } 126 127 func (network *SNetwork) GetName() string { 128 return network.Name 129 } 130 131 func (network *SNetwork) GetGlobalId() string { 132 return fmt.Sprintf("%s/%s", network.L3NetworkUUID, network.UUID) 133 } 134 135 func (network *SNetwork) IsEmulated() bool { 136 return false 137 } 138 139 func (network *SNetwork) GetStatus() string { 140 return api.NETWORK_STATUS_AVAILABLE 141 } 142 143 func (network *SNetwork) Delete() error { 144 return network.wire.vpc.region.DeleteNetwork(network.UUID) 145 } 146 147 func (region *SRegion) DeleteNetwork(networkId string) error { 148 network, err := region.GetNetwork("", "", "", networkId) 149 if err != nil { 150 return err 151 } 152 l3, err := region.GetL3Network(network.L3NetworkUUID) 153 if err != nil { 154 return err 155 } 156 if len(l3.Networks) == 1 { 157 return region.client.delete("l3-networks", l3.UUID, "") 158 } 159 return region.client.delete("l3-networks/ip-ranges", networkId, "") 160 } 161 162 func (network *SNetwork) GetIWire() cloudprovider.ICloudWire { 163 return network.wire 164 } 165 166 func (network *SNetwork) GetAllocTimeoutSeconds() int { 167 return 120 // 2 minutes 168 } 169 170 func (network *SNetwork) GetGateway() string { 171 return network.Gateway 172 } 173 174 func (network *SNetwork) GetIpStart() string { 175 return network.StartIP 176 } 177 178 func (network *SNetwork) GetIpEnd() string { 179 return network.EndIP 180 } 181 182 func (network *SNetwork) GetIPRange() netutils.IPV4AddrRange { 183 start, _ := netutils.NewIPV4Addr(network.GetIpStart()) 184 end, _ := netutils.NewIPV4Addr(network.GetIpEnd()) 185 return netutils.NewIPV4AddrRange(start, end) 186 } 187 188 func (network *SNetwork) Contains(ipAddr string) bool { 189 ip, err := netutils.NewIPV4Addr(ipAddr) 190 if err != nil { 191 return false 192 } 193 return network.GetIPRange().Contains(ip) 194 } 195 196 func (network *SNetwork) GetIpMask() int8 { 197 return int8(network.PrefixLen) 198 } 199 200 func (network *SNetwork) GetIsPublic() bool { 201 return true 202 } 203 204 func (self *SNetwork) GetPublicScope() rbacutils.TRbacScope { 205 return rbacutils.ScopeSystem 206 } 207 208 func (network *SNetwork) GetServerType() string { 209 return api.NETWORK_TYPE_GUEST 210 } 211 212 func (network *SNetwork) Refresh() error { 213 new, err := network.wire.vpc.region.GetNetwork("", network.wire.UUID, network.L3NetworkUUID, network.UUID) 214 if err != nil { 215 return err 216 } 217 return jsonutils.Update(network, new) 218 } 219 220 func (network *SNetwork) GetProjectId() string { 221 return "" 222 } 223 224 func (region *SRegion) CreateNetwork(name string, cidr string, wireId string, desc string) (*SNetwork, error) { 225 params := map[string]interface{}{ 226 "params": map[string]interface{}{ 227 "name": name, 228 "type": "L3BasicNetwork", 229 "l2NetworkUuid": wireId, 230 "category": "Private", 231 "system": false, 232 }, 233 } 234 l3 := &SL3Network{} 235 resp, err := region.client.post("l3-networks", jsonutils.Marshal(params)) 236 if err != nil { 237 return nil, err 238 } 239 err = resp.Unmarshal(l3, "inventory") 240 if err != nil { 241 return nil, err 242 } 243 region.AttachServiceForl3Network(l3.UUID, []string{"Flat", "SecurityGroup"}) 244 params = map[string]interface{}{ 245 "params": map[string]interface{}{ 246 "name": name, 247 "networkCidr": cidr, 248 }, 249 } 250 resource := fmt.Sprintf("l3-networks/%s/ip-ranges/by-cidr", l3.UUID) 251 resp, err = region.client.post(resource, jsonutils.Marshal(params)) 252 if err != nil { 253 region.client.delete("l3-networks", l3.UUID, "") 254 return nil, err 255 } 256 network := &SNetwork{} 257 return network, resp.Unmarshal(network, "inventory") 258 }