yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/zstack/eip.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 "time" 21 22 "yunion.io/x/jsonutils" 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 SEipAddress struct { 30 region *SRegion 31 multicloud.SEipBase 32 ZStackTags 33 34 ZStackBasic 35 VMNicUUID string `json:"vmNicUuid"` 36 VipUUID string `json:"vipUuid"` 37 State string `json:"state"` 38 VipIP string `json:"vipIp"` 39 GuestIP string `json:"guestIp"` 40 ZStackTime 41 } 42 43 func (region *SRegion) GetEip(eipId string) (*SEipAddress, error) { 44 eip := &SEipAddress{region: region} 45 return eip, region.client.getResource("eips", eipId, eip) 46 } 47 48 func (region *SRegion) GetEips(eipId, instanceId string) ([]SEipAddress, error) { 49 eips := []SEipAddress{} 50 params := url.Values{} 51 if len(eipId) > 0 { 52 params.Add("q", "uuid="+eipId) 53 } 54 if len(instanceId) > 0 { 55 params.Add("q", "vmNic.vmInstanceUuid="+instanceId) 56 } 57 err := region.client.listAll("eips", params, &eips) 58 if err != nil { 59 return nil, err 60 } 61 for i := 0; i < len(eips); i++ { 62 eips[i].region = region 63 } 64 return eips, nil 65 } 66 67 func (eip *SEipAddress) GetId() string { 68 return eip.UUID 69 } 70 71 func (eip *SEipAddress) GetName() string { 72 return eip.Name 73 } 74 75 func (eip *SEipAddress) GetGlobalId() string { 76 return eip.UUID 77 } 78 79 func (eip *SEipAddress) GetStatus() string { 80 return api.EIP_STATUS_READY 81 } 82 83 func (eip *SEipAddress) Refresh() error { 84 new, err := eip.region.GetEip(eip.UUID) 85 if err != nil { 86 return err 87 } 88 return jsonutils.Update(eip, new) 89 } 90 91 func (eip *SEipAddress) IsEmulated() bool { 92 return false 93 } 94 95 func (eip *SEipAddress) GetIpAddr() string { 96 return eip.VipIP 97 } 98 99 func (eip *SEipAddress) GetMode() string { 100 return api.EIP_MODE_STANDALONE_EIP 101 } 102 103 func (eip *SEipAddress) GetAssociationType() string { 104 if len(eip.GetAssociationExternalId()) > 0 { 105 return api.EIP_ASSOCIATE_TYPE_SERVER 106 } 107 return "" 108 } 109 110 func (eip *SEipAddress) GetAssociationExternalId() string { 111 if len(eip.VMNicUUID) > 0 { 112 instances, err := eip.region.GetInstances("", "", eip.VMNicUUID) 113 if err == nil && len(instances) == 1 { 114 return instances[0].UUID 115 } 116 } 117 return "" 118 } 119 120 func (eip *SEipAddress) GetBillingType() string { 121 return "" 122 } 123 124 func (eip *SEipAddress) GetCreatedAt() time.Time { 125 return eip.CreateDate 126 } 127 128 func (eip *SEipAddress) GetExpiredAt() time.Time { 129 return time.Time{} 130 } 131 132 func (eip *SEipAddress) Delete() error { 133 return eip.region.DeleteVirtualIP(eip.VipUUID) 134 } 135 136 func (eip *SEipAddress) GetBandwidth() int { 137 return 0 138 } 139 140 func (eip *SEipAddress) GetINetworkId() string { 141 vip, err := eip.region.GetVirtualIP(eip.VipUUID) 142 if err == nil { 143 return eip.region.GetNetworkId(vip) 144 } 145 return "" 146 } 147 148 func (eip *SEipAddress) GetInternetChargeType() string { 149 return api.EIP_CHARGE_TYPE_BY_TRAFFIC 150 } 151 152 func (eip *SEipAddress) Associate(conf *cloudprovider.AssociateConfig) error { 153 return eip.region.AssociateEip(conf.InstanceId, eip.UUID) 154 } 155 156 func (eip *SEipAddress) Dissociate() error { 157 return eip.region.DisassociateEip(eip.UUID) 158 } 159 160 func (eip *SEipAddress) ChangeBandwidth(bw int) error { 161 return cloudprovider.ErrNotSupported 162 } 163 164 func (eip *SEipAddress) GetProjectId() string { 165 return "" 166 } 167 168 func (region *SRegion) CreateEip(name string, vipId string, desc string) (*SEipAddress, error) { 169 params := map[string]map[string]string{ 170 "params": { 171 "name": name, 172 "description": desc, 173 "vipUuid": vipId, 174 }, 175 } 176 eip := &SEipAddress{region: region} 177 resp, err := region.client.post("eips", jsonutils.Marshal(params)) 178 if err != nil { 179 return nil, err 180 } 181 return eip, resp.Unmarshal(eip, "inventory") 182 } 183 184 func (region *SRegion) AssociateEip(instanceId, eipId string) error { 185 instance, err := region.GetInstance(instanceId) 186 if err != nil { 187 return err 188 } 189 if len(instance.VMNics) == 0 { 190 return fmt.Errorf("instance %s does not have any nic", instance.Name) 191 } 192 resource := fmt.Sprintf("eips/%s/vm-instances/nics/%s", eipId, instance.VMNics[0].UUID) 193 params := map[string]interface{}{ 194 "params": jsonutils.NewDict(), 195 } 196 _, err = region.client.post(resource, jsonutils.Marshal(params)) 197 return err 198 } 199 200 func (region *SRegion) DisassociateEip(eipId string) error { 201 resource := fmt.Sprintf("eips/%s/vm-instances/nics", eipId) 202 return region.client.delete(resource, "", "") 203 }