yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/openstack/port.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 "net/url" 19 "strings" 20 "time" 21 22 "yunion.io/x/pkg/errors" 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 ) 28 29 type DnsAssignment struct { 30 Hostname string 31 IpAddress string 32 Fqdn string 33 } 34 35 type ExtraDhcpOpt struct { 36 OptValue string 37 IpVersion int 38 OptName string 39 } 40 41 type SFixedIP struct { 42 port *SPort 43 44 IpAddress string 45 SubnetID string 46 } 47 48 func (fixip *SFixedIP) GetGlobalId() string { 49 return fixip.IpAddress 50 } 51 52 func (fixip *SFixedIP) GetIP() string { 53 return fixip.IpAddress 54 } 55 56 func (fixip *SFixedIP) GetINetworkId() string { 57 network, err := fixip.port.region.GetNetwork(fixip.SubnetID) 58 if err != nil { 59 return "" 60 } 61 for _, pool := range network.AllocationPools { 62 if pool.Contains(fixip.IpAddress) { 63 network.AllocationPools = []AllocationPool{pool} 64 return network.GetGlobalId() 65 } 66 } 67 return "" 68 } 69 70 func (fixip *SFixedIP) IsPrimary() bool { 71 return true 72 } 73 74 type SPort struct { 75 multicloud.SNetworkInterfaceBase 76 OpenStackTags 77 region *SRegion 78 AdminStateUp bool 79 AllowedAddressPairs []string 80 CreatedAt time.Time 81 DataPlaneStatus string 82 Description string 83 DeviceID string 84 DeviceOwner string 85 DnsAssignment []DnsAssignment 86 DnsDomain string 87 DnsName string 88 ExtraDhcpOpts []ExtraDhcpOpt 89 FixedIps []SFixedIP 90 ID string 91 IpAllocation string 92 MacAddress string 93 Name string 94 NetworkID string 95 ProjectID string 96 RevisionNumber int 97 SecurityGroups []string 98 Status string 99 Tags []string 100 TenantID string 101 UpdatedAt time.Time 102 QosPolicyID string 103 PortSecurityEnabled bool 104 UplinkStatusPropagation bool 105 } 106 107 func (port *SPort) GetName() string { 108 if len(port.Name) > 0 { 109 return port.Name 110 } 111 return port.ID 112 } 113 114 func (port *SPort) GetId() string { 115 return port.ID 116 } 117 118 func (port *SPort) GetGlobalId() string { 119 return port.ID 120 } 121 122 func (port *SPort) GetMacAddress() string { 123 return port.MacAddress 124 } 125 126 func (port *SPort) GetAssociateType() string { 127 switch port.DeviceOwner { 128 case "compute:nova": 129 return api.NETWORK_INTERFACE_ASSOCIATE_TYPE_SERVER 130 case "network:router_gateway", "network:dhcp", "network:router_interface": 131 return api.NETWORK_INTERFACE_ASSOCIATE_TYPE_RESERVED 132 } 133 return port.DeviceOwner 134 } 135 136 func (port *SPort) GetAssociateId() string { 137 return port.DeviceID 138 } 139 140 func (port *SPort) GetStatus() string { 141 switch port.Status { 142 case "ACTIVE", "DOWN": 143 return api.NETWORK_INTERFACE_STATUS_AVAILABLE 144 case "BUILD": 145 return api.NETWORK_INTERFACE_STATUS_CREATING 146 } 147 return port.Status 148 } 149 150 func (port *SPort) GetICloudInterfaceAddresses() ([]cloudprovider.ICloudInterfaceAddress, error) { 151 address := []cloudprovider.ICloudInterfaceAddress{} 152 for i := 0; i < len(port.FixedIps); i++ { 153 port.FixedIps[i].port = port 154 address = append(address, &port.FixedIps[i]) 155 } 156 return address, nil 157 } 158 159 func (region *SRegion) GetINetworkInterfaces() ([]cloudprovider.ICloudNetworkInterface, error) { 160 ports, err := region.GetPorts("", "") 161 if err != nil { 162 return nil, err 163 } 164 ret := []cloudprovider.ICloudNetworkInterface{} 165 for i := 0; i < len(ports); i++ { 166 if strings.HasPrefix(ports[i].DeviceOwner, "compute:") || ports[i].DeviceOwner == "network:floatingip" { 167 continue 168 } 169 ports[i].region = region 170 ret = append(ret, &ports[i]) 171 } 172 return ret, nil 173 } 174 175 func (region *SRegion) GetPort(portId string) (*SPort, error) { 176 resource := "/v2.0/ports/" + portId 177 resp, err := region.vpcGet(resource) 178 if err != nil { 179 return nil, err 180 } 181 port := &SPort{} 182 err = resp.Unmarshal(port, "port") 183 if err != nil { 184 return nil, errors.Wrap(err, "resp.Unmarshal") 185 } 186 return port, nil 187 } 188 189 func (region *SRegion) GetPorts(macAddress, deviceId string) ([]SPort, error) { 190 resource, ports := "/v2.0/ports", []SPort{} 191 query := url.Values{} 192 if len(macAddress) > 0 { 193 query.Set("mac_address", macAddress) 194 } 195 if len(deviceId) > 0 { 196 query.Set("device_id", deviceId) 197 } 198 for { 199 resp, err := region.vpcList(resource, query) 200 if err != nil { 201 return nil, errors.Wrap(err, "vpcList") 202 } 203 part := struct { 204 Ports []SPort 205 PortsLinks SNextLinks 206 }{} 207 err = resp.Unmarshal(&part) 208 if err != nil { 209 return nil, errors.Wrap(err, "resp.Unmarshal") 210 } 211 ports = append(ports, part.Ports...) 212 marker := part.PortsLinks.GetNextMark() 213 if len(marker) == 0 { 214 break 215 } 216 query.Set("marker", marker) 217 } 218 return ports, nil 219 }