mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-06-01 05:22:24 +08:00
295 lines
7.3 KiB
Go
295 lines
7.3 KiB
Go
// Copyright 2019 Yunion
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package aws
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"yunion.io/x/jsonutils"
|
|
"yunion.io/x/pkg/errors"
|
|
|
|
"yunion.io/x/onecloud/pkg/apis/billing"
|
|
api "yunion.io/x/onecloud/pkg/apis/compute"
|
|
"yunion.io/x/onecloud/pkg/cloudprovider"
|
|
"yunion.io/x/onecloud/pkg/multicloud"
|
|
)
|
|
|
|
const (
|
|
EIP_STATUS_INUSE = "InUse"
|
|
EIP_STATUS_AVAILABLE = "Available"
|
|
)
|
|
|
|
type SEipAddress struct {
|
|
region *SRegion
|
|
multicloud.SEipBase
|
|
multicloud.AwsTags
|
|
|
|
AllocationId string `xml:"allocationId"`
|
|
AssociationId string `xml:"associationId"`
|
|
CarrierIp string `xml:"carrierIp"`
|
|
CustomerOwnedIp string `xml:"customerOwnedIp"`
|
|
CustomerOwnedIpv4Pool string `xml:"customerOwnedIpv4Pool"`
|
|
Domain string `xml:"domain"`
|
|
InstanceId string `xml:"instanceId"`
|
|
NetworkBorderGroup string `xml:"networkBorderGroup"`
|
|
NetworkInterfaceId string `xml:"networkInterfaceId"`
|
|
NetworkInterfaceOwnerId string `xml:"networkInterfaceOwnerId"`
|
|
PrivateIpAddress string `xml:"privateIpAddress"`
|
|
PublicIp string `xml:"publicIp"`
|
|
PublicIpv4Pool string `xml:"publicIpv4Pool"`
|
|
}
|
|
|
|
func (self *SEipAddress) GetId() string {
|
|
return self.AllocationId
|
|
}
|
|
|
|
func (self *SEipAddress) GetName() string {
|
|
name := self.AwsTags.GetName()
|
|
if len(name) > 0 {
|
|
return name
|
|
}
|
|
return self.AllocationId
|
|
}
|
|
|
|
func (self *SEipAddress) GetGlobalId() string {
|
|
return self.AllocationId
|
|
}
|
|
|
|
func (self *SEipAddress) GetStatus() string {
|
|
return api.EIP_STATUS_READY
|
|
}
|
|
|
|
func (self *SEipAddress) Refresh() error {
|
|
if self.IsEmulated() {
|
|
return nil
|
|
}
|
|
new, err := self.region.GetEip(self.AllocationId)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return jsonutils.Update(self, new)
|
|
}
|
|
|
|
func (self *SEipAddress) IsEmulated() bool {
|
|
if self.AllocationId == self.InstanceId {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (self *SEipAddress) GetIpAddr() string {
|
|
return self.PublicIp
|
|
}
|
|
|
|
func (self *SEipAddress) GetMode() string {
|
|
if self.InstanceId == self.AllocationId {
|
|
return api.EIP_MODE_INSTANCE_PUBLICIP
|
|
}
|
|
return api.EIP_MODE_STANDALONE_EIP
|
|
}
|
|
|
|
func (self *SEipAddress) GetAssociationType() string {
|
|
if len(self.InstanceId) > 0 {
|
|
return api.EIP_ASSOCIATE_TYPE_SERVER
|
|
}
|
|
if len(self.NetworkInterfaceId) > 0 {
|
|
net, err := self.region.GetNetworkInterface(self.NetworkInterfaceId)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
switch net.InterfaceType {
|
|
case "nat_gateway":
|
|
return api.EIP_ASSOCIATE_TYPE_NAT_GATEWAY
|
|
}
|
|
}
|
|
return api.EIP_ASSOCIATE_TYPE_SERVER
|
|
}
|
|
|
|
func (self *SEipAddress) GetAssociationExternalId() string {
|
|
if len(self.InstanceId) > 0 {
|
|
return self.InstanceId
|
|
}
|
|
if len(self.NetworkInterfaceId) > 0 {
|
|
net, err := self.region.GetNetworkInterface(self.NetworkInterfaceId)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
switch net.InterfaceType {
|
|
case "nat_gateway":
|
|
nats, err := self.region.GetNatGateways(nil, net.VpcId, net.SubnetId)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
for i := range nats {
|
|
for _, addr := range nats[i].NatGatewayAddresses {
|
|
if addr.PublicIp == self.PublicIp {
|
|
return nats[i].GetGlobalId()
|
|
}
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
}
|
|
return self.InstanceId
|
|
}
|
|
|
|
func (self *SEipAddress) GetBandwidth() int {
|
|
return 0
|
|
}
|
|
|
|
func (self *SEipAddress) GetINetworkId() string {
|
|
return ""
|
|
}
|
|
|
|
func (self *SEipAddress) GetInternetChargeType() string {
|
|
return api.EIP_CHARGE_TYPE_BY_TRAFFIC
|
|
}
|
|
|
|
func (self *SEipAddress) Delete() error {
|
|
return self.region.DeallocateEIP(self.AllocationId)
|
|
}
|
|
|
|
func (self *SEipAddress) Associate(conf *cloudprovider.AssociateConfig) error {
|
|
return self.region.AssociateEip(self.AllocationId, conf.InstanceId)
|
|
}
|
|
|
|
func (self *SEipAddress) Dissociate() error {
|
|
return self.region.DissociateEip(self.AssociationId)
|
|
}
|
|
|
|
func (self *SEipAddress) ChangeBandwidth(bw int) error {
|
|
return self.region.UpdateEipBandwidth(self.AllocationId, bw)
|
|
}
|
|
|
|
func (self *SRegion) GetEips(id, ip, associateId string) ([]SEipAddress, error) {
|
|
params := map[string]string{}
|
|
if len(id) > 0 {
|
|
params["AllocationId.1"] = id
|
|
}
|
|
if len(ip) > 0 {
|
|
params["PublicIp.1"] = ip
|
|
}
|
|
idx := 1
|
|
if len(associateId) > 0 {
|
|
params[fmt.Sprintf("Filter.%d.Name", idx)] = "association-id"
|
|
params[fmt.Sprintf("Filter.%d.Value.1", idx)] = associateId
|
|
idx++
|
|
}
|
|
result := struct {
|
|
AddressesSet []SEipAddress `xml:"addressesSet>item"`
|
|
}{}
|
|
err := self.ec2Request("DescribeAddresses", params, &result)
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "DescribeAddresses")
|
|
}
|
|
return result.AddressesSet, nil
|
|
}
|
|
|
|
func (self *SRegion) GetEip(id string) (*SEipAddress, error) {
|
|
eips, err := self.GetEips(id, "", "")
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "GetEips")
|
|
}
|
|
for i := range eips {
|
|
if eips[i].GetGlobalId() == id {
|
|
eips[i].region = self
|
|
return &eips[i], nil
|
|
}
|
|
}
|
|
return nil, errors.Wrapf(cloudprovider.ErrNotFound, id)
|
|
}
|
|
|
|
func (self *SRegion) GetEipByIpAddress(eipAddress string) (*SEipAddress, error) {
|
|
eips, err := self.GetEips("", eipAddress, "")
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "GetEips")
|
|
}
|
|
for i := range eips {
|
|
if eips[i].GetIpAddr() == eipAddress {
|
|
eips[i].region = self
|
|
return &eips[i], nil
|
|
}
|
|
}
|
|
return nil, errors.Wrapf(cloudprovider.ErrNotFound, eipAddress)
|
|
}
|
|
|
|
func (self *SRegion) AllocateEIP(opts *cloudprovider.SEip) (*SEipAddress, error) {
|
|
params := map[string]string{
|
|
"Domain": "vpc",
|
|
}
|
|
if len(opts.Name) > 0 {
|
|
params["TagSpecification.1.ResourceType"] = "elastic-ip"
|
|
params["TagSpecification.1.Tag.1.Key"] = "Name"
|
|
params["TagSpecification.1.Tag.1.Value"] = opts.Name
|
|
}
|
|
ret := SEipAddress{region: self}
|
|
err := self.ec2Request("AllocateAddress", params, &ret)
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "AllocateAddress")
|
|
}
|
|
return &ret, nil
|
|
}
|
|
|
|
func (self *SRegion) CreateEIP(opts *cloudprovider.SEip) (cloudprovider.ICloudEIP, error) {
|
|
eip, err := self.AllocateEIP(opts)
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "AllocateEIP")
|
|
}
|
|
return eip, nil
|
|
}
|
|
|
|
func (self *SRegion) DeallocateEIP(eipId string) error {
|
|
params := map[string]string{
|
|
"AllocationId": eipId,
|
|
}
|
|
return self.ec2Request("ReleaseAddress", params, nil)
|
|
}
|
|
|
|
func (self *SRegion) AssociateEip(eipId string, instanceId string) error {
|
|
params := map[string]string{
|
|
"AllocationId": eipId,
|
|
"InstanceId": instanceId,
|
|
}
|
|
return self.ec2Request("AssociateAddress", params, nil)
|
|
}
|
|
|
|
func (self *SRegion) DissociateEip(insId string) error {
|
|
params := map[string]string{
|
|
"AssociationId": insId,
|
|
}
|
|
return self.ec2Request("DisassociateAddress", params, nil)
|
|
}
|
|
|
|
func (self *SRegion) UpdateEipBandwidth(eipId string, bw int) error {
|
|
return cloudprovider.ErrNotSupported
|
|
}
|
|
|
|
func (self *SEipAddress) GetBillingType() string {
|
|
return billing.BILLING_TYPE_POSTPAID
|
|
}
|
|
|
|
func (self *SEipAddress) GetCreatedAt() time.Time {
|
|
return time.Time{}
|
|
}
|
|
|
|
func (self *SEipAddress) GetExpiredAt() time.Time {
|
|
return time.Time{}
|
|
}
|
|
|
|
func (self *SEipAddress) GetProjectId() string {
|
|
return ""
|
|
}
|