mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-10-30 18:23:35 +08:00
222 lines
5.8 KiB
Go
222 lines
5.8 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 apsara
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"yunion.io/x/jsonutils"
|
|
"yunion.io/x/log"
|
|
|
|
api "yunion.io/x/onecloud/pkg/apis/compute"
|
|
"yunion.io/x/onecloud/pkg/cloudprovider"
|
|
"yunion.io/x/onecloud/pkg/multicloud"
|
|
)
|
|
|
|
type SSNATTableEntry struct {
|
|
multicloud.SResourceBase
|
|
multicloud.ApsaraTags
|
|
nat *SNatGetway
|
|
|
|
SnatEntryId string
|
|
SnatEntryName string
|
|
SnatIp string
|
|
SnatTableId string `json:"snat_table_id"`
|
|
SourceCIDR string `json:"source_cidr"`
|
|
SourceVSwitchId string `json:"source_vswitch_id"`
|
|
Status string
|
|
}
|
|
|
|
func (stable *SSNATTableEntry) GetName() string {
|
|
if len(stable.SnatEntryName) > 0 {
|
|
return stable.SnatEntryName
|
|
}
|
|
return stable.SnatEntryId
|
|
}
|
|
|
|
func (stable *SSNATTableEntry) GetId() string {
|
|
return stable.SnatEntryId
|
|
}
|
|
|
|
func (stable *SSNATTableEntry) GetGlobalId() string {
|
|
return stable.SnatEntryId
|
|
}
|
|
|
|
func (stable *SSNATTableEntry) GetStatus() string {
|
|
switch stable.Status {
|
|
case "Available":
|
|
return api.NAT_STAUTS_AVAILABLE
|
|
default:
|
|
return api.NAT_STATUS_UNKNOWN
|
|
}
|
|
}
|
|
|
|
func (stable *SSNATTableEntry) GetIP() string {
|
|
return stable.SnatIp
|
|
}
|
|
|
|
func (stable *SSNATTableEntry) GetSourceCIDR() string {
|
|
return stable.SourceCIDR
|
|
}
|
|
|
|
func (stable *SSNATTableEntry) GetNetworkId() string {
|
|
return stable.SourceVSwitchId
|
|
}
|
|
|
|
func (stable *SSNATTableEntry) Delete() error {
|
|
return stable.nat.vpc.region.DeleteSnatEntry(stable.SnatTableId, stable.GetId())
|
|
}
|
|
|
|
func (self *SRegion) GetSNATEntries(tableId string, offset, limit int) ([]SSNATTableEntry, int, error) {
|
|
if limit > 50 || limit <= 0 {
|
|
limit = 50
|
|
}
|
|
params := make(map[string]string)
|
|
params["RegionId"] = self.RegionId
|
|
params["PageSize"] = fmt.Sprintf("%d", limit)
|
|
params["PageNumber"] = fmt.Sprintf("%d", (offset/limit)+1)
|
|
params["SnatTableId"] = tableId
|
|
|
|
body, err := self.vpcRequest("DescribeSnatTableEntries", params)
|
|
if err != nil {
|
|
log.Errorf("DescribeSnatTableEntries fail %s", err)
|
|
return nil, 0, err
|
|
}
|
|
|
|
if self.client.debug {
|
|
log.Debugf("%s", body.PrettyString())
|
|
}
|
|
|
|
entries := make([]SSNATTableEntry, 0)
|
|
err = body.Unmarshal(&entries, "SnatTableEntries", "SnatTableEntry")
|
|
if err != nil {
|
|
log.Errorf("Unmarshal entries fail %s", err)
|
|
return nil, 0, err
|
|
}
|
|
total, _ := body.Int("TotalCount")
|
|
return entries, int(total), nil
|
|
}
|
|
|
|
func (self *SRegion) GetSNATEntry(tableID, SNATEntryID string) (SSNATTableEntry, error) {
|
|
params := make(map[string]string)
|
|
params["RegionId"] = self.RegionId
|
|
params["SnatTableId"] = tableID
|
|
params["SnatEntryId"] = SNATEntryID
|
|
|
|
body, err := self.vpcRequest("DescribeSnatTableEntries", params)
|
|
if err != nil {
|
|
log.Errorf("DescribeSnatTableEntries fail %s", err)
|
|
return SSNATTableEntry{}, err
|
|
}
|
|
|
|
if self.client.debug {
|
|
log.Debugf("%s", body.PrettyString())
|
|
}
|
|
|
|
entries := make([]SSNATTableEntry, 0)
|
|
err = body.Unmarshal(&entries, "SnatTableEntries", "SnatTableEntry")
|
|
if err != nil {
|
|
log.Errorf("Unmarshal entries fail %s", err)
|
|
return SSNATTableEntry{}, err
|
|
}
|
|
if len(entries) == 0 {
|
|
return SSNATTableEntry{}, cloudprovider.ErrNotFound
|
|
}
|
|
return entries[0], nil
|
|
|
|
}
|
|
|
|
func (region *SRegion) CreateSNATTableEntry(rule cloudprovider.SNatSRule, tableID string) (string, error) {
|
|
params := make(map[string]string)
|
|
params["RegionId"] = region.RegionId
|
|
params["SnatTableId"] = tableID
|
|
params["SnatIp"] = rule.ExternalIP
|
|
if len(rule.NetworkID) != 0 {
|
|
params["SourceVSwitchId"] = rule.NetworkID
|
|
}
|
|
if len(rule.SourceCIDR) != 0 {
|
|
params["SourceCIDR"] = rule.SourceCIDR
|
|
}
|
|
body, err := region.vpcRequest("CreateSnatEntry", params)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
entryID, _ := body.GetString("SnatEntryId")
|
|
return entryID, nil
|
|
}
|
|
|
|
func (region *SRegion) DeleteSnatEntry(tableId string, entryId string) error {
|
|
params := make(map[string]string)
|
|
params["RegionId"] = region.RegionId
|
|
params["SnatTableId"] = tableId
|
|
params["SnatEntryId"] = entryId
|
|
_, err := region.vpcRequest("DeleteSnatEntry", params)
|
|
return err
|
|
}
|
|
|
|
func (nat *SNatGetway) getSnatEntriesForTable(tblId string) ([]SSNATTableEntry, error) {
|
|
entries := make([]SSNATTableEntry, 0)
|
|
entryTotal := -1
|
|
for entryTotal < 0 || len(entries) < entryTotal {
|
|
parts, total, err := nat.vpc.region.GetSNATEntries(tblId, len(entries), 50)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(parts) > 0 {
|
|
entries = append(entries, parts...)
|
|
}
|
|
entryTotal = total
|
|
}
|
|
return entries, nil
|
|
}
|
|
|
|
func (nat *SNatGetway) getSnatEntries() ([]SSNATTableEntry, error) {
|
|
entries := make([]SSNATTableEntry, 0)
|
|
for i := range nat.SnatTableIds.SnatTableId {
|
|
sentries, err := nat.getSnatEntriesForTable(nat.SnatTableIds.SnatTableId[i])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
entries = append(entries, sentries...)
|
|
}
|
|
return entries, nil
|
|
}
|
|
|
|
func (nat *SNatGetway) dissociateWithVswitch(vswitchId string) error {
|
|
entries, err := nat.getSnatEntries()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for i := range entries {
|
|
log.Debugf("%v", entries[i])
|
|
if entries[i].SourceVSwitchId == vswitchId {
|
|
err := nat.vpc.region.DeleteSnatEntry(entries[i].SnatTableId, entries[i].SnatEntryId)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (stable *SSNATTableEntry) Refresh() error {
|
|
new, err := stable.nat.vpc.region.GetSNATEntry(stable.SnatTableId, stable.SnatEntryId)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return jsonutils.Update(stable, new)
|
|
}
|