Merge pull request #7952 from lvyangyang/vpc-peering-connection

Vpc peering connection
This commit is contained in:
yunion-ci-robot
2020-10-12 14:21:18 +08:00
committed by GitHub
42 changed files with 2755 additions and 90 deletions
@@ -0,0 +1,31 @@
// 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 compute
import (
"yunion.io/x/onecloud/cmd/climc/shell"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
func init() {
cmd := shell.NewResourceCmd(&modules.VpcPeeringConnections).WithKeyword("vpc-peering-connection")
cmd.List(&options.VpcPeeringConnectionListOptions{})
cmd.Show(&options.VpcPeeringConnectionIdOptions{})
cmd.Create(&options.VpcPeeringConnectionCreateOptions{})
cmd.Delete(&options.VpcPeeringConnectionIdOptions{})
cmd.Perform("sync", &options.VpcPeeringConnectionIdOptions{})
cmd.Perform("syncstatus", &options.VpcPeeringConnectionIdOptions{})
}
@@ -0,0 +1,52 @@
// 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 compute
import "yunion.io/x/onecloud/pkg/apis"
const (
VPC_PEERING_CONNECTION_STATUS_CREATING = "creating"
VPC_PEERING_CONNECTION_STATUS_CREATE_FAILED = "create_failed"
VPC_PEERING_CONNECTION_STATUS_DELETE_FAILED = "delete_failed"
VPC_PEERING_CONNECTION_STATUS_PENDING_ACCEPT = "pending-acceptance"
VPC_PEERING_CONNECTION_STATUS_ACTIVE = "active"
VPC_PEERING_CONNECTION_STATUS_DELETING = "deleting"
VPC_PEERING_CONNECTION_STATUS_UNKNOWN = "unknown"
)
type VpcPeeringConnectionDetails struct {
apis.EnabledStatusInfrasResourceBaseDetails
VpcName string
PeerVpcName string
}
type VpcPeeringConnectionCreateInput struct {
apis.EnabledStatusInfrasResourceBaseCreateInput
SVpcResourceBase
PeerVpcId string
//跨区域vpc对等连接带宽,仅对腾讯云有效
//单位Mbps,可选值 10,20,50,100,200,500,1000
Bandwidth int
}
type VpcPeeringConnectionListInput struct {
apis.EnabledStatusInfrasResourceBaseListInput
VpcId string
PeerVpcId string
}
type VpcPeeringConnectionUpdateInput struct {
apis.EnabledStatusInfrasResourceBaseUpdateInput
}
+21
View File
@@ -204,6 +204,11 @@ type ICloudProviderFactory interface {
IsSystemCloudpolicyUnified() bool // 国内国外权限是否一致
IsSupportCrossCloudEnvVpcPeering() bool
IsSupportCrossRegionVpcPeering() bool
IsSupportVpcPeeringVpcCidrOverlap() bool
ValidateCrossRegionVpcPeeringBandWidth(bandwidth int) error
GetSupportedDnsZoneTypes() []TDnsZoneType
GetSupportedDnsTypes() map[TDnsZoneType][]TDnsType
GetSupportedDnsPolicyTypes() map[TDnsZoneType][]TDnsPolicyType
@@ -598,6 +603,22 @@ func (factory *baseProviderFactory) IsSystemCloudpolicyUnified() bool {
return true
}
func (factory *baseProviderFactory) IsSupportCrossCloudEnvVpcPeering() bool {
return false
}
func (factory *baseProviderFactory) IsSupportCrossRegionVpcPeering() bool {
return false
}
func (factory *baseProviderFactory) IsSupportVpcPeeringVpcCidrOverlap() bool {
return false
}
func (factory *baseProviderFactory) ValidateCrossRegionVpcPeeringBandWidth(bandwidth int) error {
return nil
}
func (factory *baseProviderFactory) GetSupportedDnsZoneTypes() []TDnsZoneType {
return []TDnsZoneType{}
}
+16
View File
@@ -447,6 +447,12 @@ type ICloudVpc interface {
GetIWireById(wireId string) (ICloudWire, error)
GetINatGateways() ([]ICloudNatGateway, error)
GetICloudVpcPeeringConnections() ([]ICloudVpcPeeringConnection, error)
GetICloudVpcPeeringConnectionById(id string) (ICloudVpcPeeringConnection, error)
CreateICloudVpcPeeringConnection(opts *VpcPeeringConnectionCreateOptions) (ICloudVpcPeeringConnection, error)
AcceptICloudVpcPeeringConnection(id string) error
GetAuthorityOwnerId() string
}
type ICloudWire interface {
@@ -1053,3 +1059,13 @@ type ICloudDnsRecordSet interface {
GetPolicyValue() TDnsPolicyValue
GetPolicyOptions() *jsonutils.JSONDict
}
type ICloudVpcPeeringConnection interface {
ICloudResource
GetPeerVpcId() string
GetPeerAccountId() string
GetEnabled() bool
Delete() error
}
@@ -0,0 +1,24 @@
// 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 cloudprovider
type VpcPeeringConnectionCreateOptions struct {
Name string
Desc string
PeerVpcId string
PeerAccountId string
PeerRegionId string
Bandwidth int //qcloud cross region,Mbps
}
+20
View File
@@ -250,10 +250,30 @@ func syncRegionVPCs(ctx context.Context, userCred mcclient.TokenCredential, sync
}
syncVpcRouteTables(ctx, userCred, syncResults, provider, &localVpcs[j], remoteVpcs[j], syncRange)
syncVpcNatgateways(ctx, userCred, syncResults, provider, &localVpcs[j], remoteVpcs[j], syncRange)
syncVpcPeerConnections(ctx, userCred, syncResults, provider, &localVpcs[j], remoteVpcs[j], syncRange)
}()
}
}
func syncVpcPeerConnections(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, provider *SCloudprovider, localVpc *SVpc, remoteVpc cloudprovider.ICloudVpc, syncRange *SSyncRange) {
peerConnections, err := remoteVpc.GetICloudVpcPeeringConnections()
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotImplemented || errors.Cause(err) == cloudprovider.ErrNotSupported {
return
}
log.Errorf("GetICloudVpcPeeringConnections for vpc %s failed %v", localVpc.Name, err)
return
}
result := localVpc.SyncVpcPeeringConnections(ctx, userCred, peerConnections)
syncResults.Add(VpcPeeringConnectionManager, result)
log.Infof("SyncVpcPeeringConnections for vpc %s result: %s", localVpc.Name, result.Result())
if result.IsError() {
return
}
}
func syncVpcSecGroup(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, provider *SCloudprovider, localVpc *SVpc, remoteVpc cloudprovider.ICloudVpc, syncRange *SSyncRange) {
secgroups, err := remoteVpc.GetISecurityGroups()
if err != nil {
+26 -1
View File
@@ -1014,11 +1014,30 @@ func (vpc *SVpc) purgeWires(ctx context.Context, userCred mcclient.TokenCredenti
return nil
}
func (vpc *SVpc) purgeVpcPeeringConnections(ctx context.Context, userCred mcclient.TokenCredential) error {
vpcPCs, err := vpc.GetVpcPeeringConnections()
if err != nil {
return err
}
for i := range vpcPCs {
err := vpcPCs[i].purge(ctx, userCred)
if err != nil {
return err
}
}
return nil
}
func (vpc *SVpc) Purge(ctx context.Context, userCred mcclient.TokenCredential) error {
lockman.LockObject(ctx, vpc)
defer lockman.ReleaseObject(ctx, vpc)
err := vpc.purgeWires(ctx, userCred)
err := vpc.purgeVpcPeeringConnections(ctx, userCred)
if err != nil {
return err
}
err = vpc.purgeWires(ctx, userCred)
if err != nil {
return err
}
@@ -1718,3 +1737,9 @@ func (manager *SPolicyDefinitionManager) purgeAll(ctx context.Context, userCred
}
return nil
}
func (vpcPC *SVpcPeeringConnection) purge(ctx context.Context, userCred mcclient.TokenCredential) error {
lockman.LockObject(ctx, vpcPC)
defer lockman.ReleaseObject(ctx, vpcPC)
return vpcPC.RealDelete(ctx, userCred)
}
@@ -0,0 +1,370 @@
// 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 models
import (
"context"
"database/sql"
"strings"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/netutils"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SVpcPeeringConnectionManager struct {
db.SEnabledStatusInfrasResourceBaseManager
db.SExternalizedResourceBaseManager
}
var VpcPeeringConnectionManager *SVpcPeeringConnectionManager
func init() {
VpcPeeringConnectionManager = &SVpcPeeringConnectionManager{
SEnabledStatusInfrasResourceBaseManager: db.NewEnabledStatusInfrasResourceBaseManager(
SVpcPeeringConnection{},
"vpc_peering_connections_tbl",
"vpc_peering_connection",
"vpc_peering_connections",
),
}
VpcPeeringConnectionManager.SetVirtualObject(VpcPeeringConnectionManager)
}
type SVpcPeeringConnection struct {
db.SEnabledStatusInfrasResourceBase
db.SExternalizedResourceBase
SVpcResourceBase
PeerVpcId string `width:"36" charset:"ascii" nullable:"true" list:"domain" create:"required" json:"peer_vpc_id"`
PeerAccountId string `width:"36" charset:"ascii" nullable:"true" list:"domain"`
Bandwidth int `nullable:"false" default:"0" list:"user" create:"optional"`
}
func (manager *SVpcPeeringConnectionManager) GetContextManagers() [][]db.IModelManager {
return [][]db.IModelManager{
{VpcManager},
}
}
// 列表
func (manager *SVpcPeeringConnectionManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.VpcPeeringConnectionListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SEnabledStatusInfrasResourceBaseManager.ListItemFilter(ctx, q, userCred, query.EnabledStatusInfrasResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SEnabledStatusInfrasResourceBaseManager.ListItemFilter")
}
if len(query.VpcId) > 0 {
vpc, err := VpcManager.FetchByIdOrName(userCred, query.VpcId)
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2("vpc_id", query.VpcId)
}
return nil, httperrors.NewGeneralError(err)
}
q = q.Equals("vpc_id", vpc.GetId())
}
if len(query.PeerVpcId) > 0 {
peerVpc, err := VpcManager.FetchByIdOrName(userCred, query.PeerVpcId)
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError("peer_vpc_id", query.PeerVpcId)
}
return nil, httperrors.NewGeneralError(err)
}
q = q.Equals("peer_vpc_id", peerVpc.GetId())
}
return q, nil
}
// 创建
func (manager *SVpcPeeringConnectionManager) ValidateCreateData(
ctx context.Context,
userCred mcclient.TokenCredential,
ownerId mcclient.IIdentityProvider,
query jsonutils.JSONObject,
input api.VpcPeeringConnectionCreateInput,
) (api.VpcPeeringConnectionCreateInput, error) {
var err error
input.EnabledStatusInfrasResourceBaseCreateInput, err = manager.SEnabledStatusInfrasResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.EnabledStatusInfrasResourceBaseCreateInput)
if err != nil {
return input, err
}
if len(input.VpcId) == 0 {
return input, httperrors.NewInputParameterError("vpc_id")
}
// get vpc ,peerVpc
_vpc, err := VpcManager.FetchByIdOrName(userCred, input.VpcId)
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
return input, httperrors.NewResourceNotFoundError2("vpc", input.VpcId)
}
return input, httperrors.NewGeneralError(err)
}
vpc := _vpc.(*SVpc)
_peerVpc, err := VpcManager.FetchByIdOrName(userCred, input.PeerVpcId)
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
return input, httperrors.NewResourceNotFoundError2("Peervpc", input.PeerVpcId)
}
return input, httperrors.NewGeneralError(err)
}
peerVpc := _peerVpc.(*SVpc)
// get account,providerFactory
account := vpc.GetCloudaccount()
peerAccount := peerVpc.GetCloudaccount()
if account.Provider != peerAccount.Provider {
return input, httperrors.NewNotSupportedError("vpc on different cloudprovider peering is not supported")
}
factory, err := cloudprovider.GetProviderFactory(account.Provider)
if err != nil {
return input, httperrors.NewGeneralError(errors.Wrapf(err, "cloudprovider.GetProviderFactory(%s)", account.Provider))
}
// check vpc ip range overlap
if !factory.IsSupportVpcPeeringVpcCidrOverlap() {
vpcIpv4Ranges := []netutils.IPV4AddrRange{}
peervpcIpv4Ranges := []netutils.IPV4AddrRange{}
vpcCidrBlocks := strings.Split(vpc.CidrBlock, ",")
peervpcCidrBlocks := strings.Split(peerVpc.CidrBlock, ",")
for i := range vpcCidrBlocks {
vpcIpv4Range, err := newIPv4RangeFromCIDR(vpcCidrBlocks[i])
if err != nil {
return input, httperrors.NewGeneralError(errors.Wrapf(err, "convert vpc cidr %s to ipv4range error", vpcCidrBlocks[i]))
}
vpcIpv4Ranges = append(vpcIpv4Ranges, vpcIpv4Range)
}
for i := range peervpcCidrBlocks {
peervpcIpv4Range, err := newIPv4RangeFromCIDR(peervpcCidrBlocks[i])
if err != nil {
return input, httperrors.NewGeneralError(errors.Wrapf(err, "convert vpc cidr %s to ipv4range error", peervpcCidrBlocks[i]))
}
peervpcIpv4Ranges = append(peervpcIpv4Ranges, peervpcIpv4Range)
}
for i := range vpcIpv4Ranges {
for j := range peervpcIpv4Ranges {
if vpcIpv4Ranges[i].IsOverlap(peervpcIpv4Ranges[j]) {
return input, httperrors.NewNotSupportedError("ipv4 range overlap")
}
}
}
}
CrossCloudEnv := account.AccessUrl != peerAccount.AccessUrl
CrossRegion := vpc.CloudregionId != peerVpc.CloudregionId
if CrossCloudEnv && !factory.IsSupportCrossCloudEnvVpcPeering() {
return input, httperrors.NewNotSupportedError("cloudprovider %s %s %s %s %s not supported CrossCloud vpcpeering", account.Provider, account.AccessUrl, vpc.CloudregionId, peerAccount.AccessUrl, peerVpc.CloudregionId)
}
if CrossRegion && !factory.IsSupportCrossRegionVpcPeering() {
return input, httperrors.NewNotSupportedError("cloudprovider %s %s %s %s %s not supported CrossRegion vpcpeering", account.Provider, account.AccessUrl, vpc.CloudregionId, peerAccount.AccessUrl, peerVpc.CloudregionId)
}
if CrossRegion {
err := factory.ValidateCrossRegionVpcPeeringBandWidth(input.Bandwidth)
if err != nil {
return input, err
}
}
// existed peer check
vpcPC := SVpcPeeringConnection{}
err = manager.Query().Equals("vpc_id", vpc.Id).Equals("peer_vpc_id", peerVpc.Id).First(&vpcPC)
if err == nil {
return input, httperrors.NewNotSupportedError("vpc %s and vpc %s have already connected", input.VpcId, input.PeerVpcId)
} else {
if errors.Cause(err) != sql.ErrNoRows {
return input, httperrors.NewGeneralError(err)
}
}
return input, nil
}
func (self *SVpcPeeringConnection) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
params := jsonutils.NewDict()
task, err := taskman.TaskManager.NewTask(ctx, "VpcPeeringConnectionCreateTask", self, userCred, params, "", "", nil)
if err != nil {
return
}
self.SetStatus(userCred, api.VPC_PEERING_CONNECTION_STATUS_CREATING, "")
task.ScheduleRun(nil)
}
func (self *SVpcPeeringConnection) GetExtraDetails(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
isList bool,
) (api.VpcPeeringConnectionDetails, error) {
return api.VpcPeeringConnectionDetails{}, nil
}
func (manager *SVpcPeeringConnectionManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.VpcPeeringConnectionDetails {
rows := make([]api.VpcPeeringConnectionDetails, len(objs))
stdRows := manager.SEnabledStatusInfrasResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
vpcIds := make([]string, len(objs))
peerVpcIds := make([]string, len(objs))
for i := range rows {
rows[i] = api.VpcPeeringConnectionDetails{
EnabledStatusInfrasResourceBaseDetails: stdRows[i],
}
vpcPC := objs[i].(*SVpcPeeringConnection)
vpcIds[i] = vpcPC.VpcId
peerVpcIds[i] = vpcPC.PeerVpcId
}
vpcMap, err := db.FetchIdNameMap2(VpcManager, vpcIds)
if err != nil {
return rows
}
peerVpcMap, err := db.FetchIdNameMap2(VpcManager, peerVpcIds)
if err != nil {
return rows
}
for i := range rows {
rows[i].VpcName, _ = vpcMap[vpcIds[i]]
rows[i].PeerVpcName, _ = peerVpcMap[peerVpcIds[i]]
}
return rows
}
func (self *SVpcPeeringConnection) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
return self.StartDeleteVpcPeeringConnectionTask(ctx, userCred)
}
func (self *SVpcPeeringConnection) StartDeleteVpcPeeringConnectionTask(ctx context.Context, userCred mcclient.TokenCredential) error {
self.SetStatus(userCred, api.VPC_PEERING_CONNECTION_STATUS_DELETING, "")
task, err := taskman.TaskManager.NewTask(ctx, "VpcPeeringConnectionDeleteTask", self, userCred, nil, "", "", nil)
if err != nil {
return errors.Wrap(err, "Start VpcPeeringConnectionDeleteTask fail")
}
task.ScheduleRun(nil)
return nil
}
func (self *SVpcPeeringConnection) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return nil
}
func (self *SVpcPeeringConnection) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.SEnabledStatusInfrasResourceBase.Delete(ctx, userCred)
}
func (self *SVpcPeeringConnection) AllowPerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return db.IsAdminAllowPerform(userCred, self, "syncstatus")
}
// 同步状态
func (self *SVpcPeeringConnection) PerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.VpcSyncstatusInput) (jsonutils.JSONObject, error) {
return nil, StartResourceSyncStatusTask(ctx, userCred, self, "VpcPeeringConnectionSyncstatusTask", "")
}
func (manager *SVpcPeeringConnectionManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.VpcPeeringConnectionListInput,
) (*sqlchemy.SQuery, error) {
q, err := manager.SEnabledStatusInfrasResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.EnabledStatusInfrasResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SEnabledStatusInfrasResourceBaseManager.OrderByExtraFields")
}
return q, nil
}
func (manager *SVpcPeeringConnectionManager) ListItemExportKeys(ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
keys stringutils2.SSortedStrings,
) (*sqlchemy.SQuery, error) {
q, err := manager.SEnabledStatusInfrasResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SEnabledStatusInfrasResourceBaseManager.ListItemExportKeys")
}
return q, nil
}
func (self *SVpcPeeringConnection) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.VpcPeeringConnectionUpdateInput) (api.VpcPeeringConnectionUpdateInput, error) {
var err error
input.EnabledStatusInfrasResourceBaseUpdateInput, err = self.SEnabledStatusInfrasResourceBase.ValidateUpdateData(ctx, userCred, query, input.EnabledStatusInfrasResourceBaseUpdateInput)
if err != nil {
return input, err
}
return input, nil
}
func (self *SVpcPeeringConnection) syncRemove(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.RealDelete(ctx, userCred)
}
func (self *SVpcPeeringConnection) SyncWithCloudPeerConnection(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudVpcPeeringConnection, provider *SCloudprovider) error {
_, err := db.Update(self, func() error {
self.Status = ext.GetStatus()
self.ExternalId = ext.GetGlobalId()
self.PeerAccountId = ext.GetPeerAccountId()
return nil
})
if err != nil {
return errors.Wrapf(err, "db.Update")
}
if provider != nil {
SyncCloudDomain(userCred, self, provider.GetOwnerId())
self.SyncShareState(ctx, userCred, provider.getAccountShareInfo())
}
return nil
}
func (self *SVpcPeeringConnection) GetVpc() (*SVpc, error) {
vpc, err := VpcManager.FetchById(self.VpcId)
if err != nil {
return nil, errors.Wrapf(err, "VpcManager.FetchById(%s)", self.VpcId)
}
return vpc.(*SVpc), nil
}
func (self *SVpcPeeringConnection) GetPeerVpc() (*SVpc, error) {
vpc, err := VpcManager.FetchById(self.PeerVpcId)
if err != nil {
return nil, errors.Wrapf(err, "VpcManager.FetchById(%s)", self.VpcId)
}
return vpc.(*SVpc), nil
}
+161
View File
@@ -23,6 +23,7 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/tristate"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/pkg/util/netutils"
"yunion.io/x/pkg/utils"
@@ -143,6 +144,45 @@ func (self *SVpc) GetNatgateways() ([]SNatGateway, error) {
return nats, nil
}
func (self *SVpc) getRequesterVpcPeeringConnectionQuery() *sqlchemy.SQuery {
return VpcPeeringConnectionManager.Query().Equals("vpc_id", self.Id)
}
func (self *SVpc) getAccepterVpcPeeringConnectionQuery() *sqlchemy.SQuery {
return VpcPeeringConnectionManager.Query().Equals("peer_vpc_id", self.Id)
}
func (self *SVpc) GetRequesterVpcPeeringConnections() ([]SVpcPeeringConnection, error) {
vpcPC := []SVpcPeeringConnection{}
err := db.FetchModelObjects(VpcPeeringConnectionManager, self.getRequesterVpcPeeringConnectionQuery(), &vpcPC)
if err != nil {
return nil, err
}
return vpcPC, nil
}
func (self *SVpc) GetAccepterVpcPeeringConnections() ([]SVpcPeeringConnection, error) {
vpcPC := []SVpcPeeringConnection{}
err := db.FetchModelObjects(VpcPeeringConnectionManager, self.getAccepterVpcPeeringConnectionQuery(), &vpcPC)
if err != nil {
return nil, err
}
return vpcPC, nil
}
func (self *SVpc) GetVpcPeeringConnectionCount() (int, error) {
q := self.getRequesterVpcPeeringConnectionQuery()
requesterPeerCount, err := q.CountWithError()
if err != nil {
return 0, err
}
q = self.getRequesterVpcPeeringConnectionQuery()
accepterPeerCount, err := q.CountWithError()
if err != nil {
return 0, err
}
return requesterPeerCount + accepterPeerCount, nil
}
func (self *SVpc) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.VpcUpdateInput) (api.VpcUpdateInput, error) {
if input.ExternalAccessMode != "" {
if !utils.IsInStringArray(input.ExternalAccessMode, api.VPC_EXTERNAL_ACCESS_MODES) {
@@ -174,6 +214,14 @@ func (self *SVpc) ValidateDeleteCondition(ctx context.Context) error {
if self.Id == api.DEFAULT_VPC_ID {
return httperrors.NewProtectedResourceError("not allow to delete default vpc")
}
cnt, err = self.GetVpcPeeringConnectionCount()
if err != nil {
return httperrors.NewInternalServerError("GetRequesterVpcPeeringConnections fail %v", err)
}
if cnt > 0 {
return httperrors.NewNotEmptyError("VPC peering not empty, please delete vpc peering first")
}
return self.SEnabledStatusInfrasResourceBase.ValidateDeleteCondition(ctx)
}
@@ -589,6 +637,22 @@ func (self *SVpc) markAllNetworksUnknown(userCred mcclient.TokenCredential) erro
return nil
}
func (self *SVpc) SyncRouteTables(ctx context.Context, userCred mcclient.TokenCredential) error {
ivpc, err := self.GetIVpc()
if err != nil {
return errors.Wrap(err, "self.GetIVpc()")
}
routeTables, err := ivpc.GetIRouteTables()
if err != nil {
return errors.Wrapf(err, "GetIRouteTables for vpc %s failed", ivpc.GetId())
}
_, _, result := RouteTableManager.SyncRouteTables(ctx, userCred, self, routeTables, self.GetCloudprovider())
if result.IsError() {
return errors.Wrapf(result.AllError(), "RouteTableManager.SyncRouteTables(%s,%s)", jsonutils.Marshal(self).String(), jsonutils.Marshal(routeTables).String())
}
return nil
}
func (manager *SVpcManager) InitializeData() error {
if vpcObj, err := manager.FetchById(api.DEFAULT_VPC_ID); err != nil {
if err == sql.ErrNoRows {
@@ -1357,3 +1421,100 @@ func (vpc *SVpc) PerformChangeOwner(ctx context.Context, userCred mcclient.Token
return nil, nil
}
func (self *SVpc) GetVpcPeeringConnections() ([]SVpcPeeringConnection, error) {
q := VpcPeeringConnectionManager.Query().Equals("vpc_id", self.Id)
peers := []SVpcPeeringConnection{}
err := db.FetchModelObjects(VpcPeeringConnectionManager, q, &peers)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchModelObjects")
}
return peers, nil
}
func (self *SVpc) SyncVpcPeeringConnections(ctx context.Context, userCred mcclient.TokenCredential, exts []cloudprovider.ICloudVpcPeeringConnection) compare.SyncResult {
result := compare.SyncResult{}
dbPeers, err := self.GetVpcPeeringConnections()
if err != nil {
result.Error(errors.Wrapf(err, "GetVpcPeeringConnections"))
return result
}
provider := self.GetCloudprovider()
removed := make([]SVpcPeeringConnection, 0)
commondb := make([]SVpcPeeringConnection, 0)
commonext := make([]cloudprovider.ICloudVpcPeeringConnection, 0)
added := make([]cloudprovider.ICloudVpcPeeringConnection, 0)
err = compare.CompareSets(dbPeers, exts, &removed, &commondb, &commonext, &added)
if err != nil {
result.Error(err)
return result
}
for i := 0; i < len(removed); i += 1 {
if len(removed[i].ExternalId) > 0 {
err = removed[i].syncRemove(ctx, userCred)
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
}
for i := 0; i < len(commondb); i += 1 {
err = commondb[i].SyncWithCloudPeerConnection(ctx, userCred, commonext[i], provider)
if err != nil {
result.UpdateError(err)
continue
}
syncMetadata(ctx, userCred, &commondb[i], commonext[i])
result.Update()
}
for i := 0; i < len(added); i += 1 {
_, err := self.newFromCloudPeerConnection(ctx, userCred, added[i], provider)
if err != nil {
result.AddError(errors.Wrapf(err, "newFromCloudPeerConnection"))
continue
}
result.Add()
}
return result
}
func (self *SVpc) newFromCloudPeerConnection(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudVpcPeeringConnection, provider *SCloudprovider) (*SVpcPeeringConnection, error) {
peer := &SVpcPeeringConnection{}
peer.SetModelManager(VpcPeeringConnectionManager, peer)
peer.Name, _ = db.GenerateName(VpcPeeringConnectionManager, provider.GetOwnerId(), ext.GetName())
peer.ExternalId = ext.GetGlobalId()
peer.Status = ext.GetStatus()
peer.VpcId = self.Id
peer.Enabled = tristate.True
peer.PeerVpcId = ext.GetPeerVpcId()
manager := self.GetCloudprovider()
peerVpc, _ := db.FetchByExternalIdAndManagerId(VpcManager, peer.PeerVpcId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
managerQ := CloudproviderManager.Query("id").Equals("provider", manager.Provider)
return q.In("manager_id", managerQ.SubQuery())
})
if peerVpc != nil {
peer.PeerVpcId = peerVpc.GetId()
}
peer.PeerAccountId = ext.GetPeerAccountId()
err := VpcPeeringConnectionManager.TableSpec().Insert(ctx, peer)
if err != nil {
return nil, errors.Wrapf(err, "Insert")
}
if provider != nil {
SyncCloudDomain(userCred, peer, provider.GetOwnerId())
peer.SyncShareState(ctx, userCred, provider.getAccountShareInfo())
}
db.OpsLog.LogEvent(peer, db.ACT_CREATE, peer.GetShortDesc(ctx), userCred)
return peer, nil
}
+2
View File
@@ -194,6 +194,8 @@ func InitHandlers(app *appsrv.Application) {
models.DnsZoneCacheManager,
models.DnsRecordSetManager,
models.DnsTrafficPolicyManager,
models.VpcPeeringConnectionManager,
} {
db.RegisterModelManager(manager)
handler := db.NewModelHandler(manager)
@@ -0,0 +1,104 @@
// 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 tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type VpcPeeringConnectionCreateTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(VpcPeeringConnectionCreateTask{})
}
func (self *VpcPeeringConnectionCreateTask) taskFailed(ctx context.Context, peer *models.SVpcPeeringConnection, err error) {
peer.SetStatus(self.UserCred, api.VPC_PEERING_CONNECTION_STATUS_CREATE_FAILED, err.Error())
db.OpsLog.LogEvent(peer, db.ACT_ALLOCATE_FAIL, err, self.UserCred)
logclient.AddActionLogWithStartable(self, peer, logclient.ACT_ALLOCATE, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *VpcPeeringConnectionCreateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
peer := obj.(*models.SVpcPeeringConnection)
vpc, err := peer.GetVpc()
if err != nil {
self.taskFailed(ctx, peer, errors.Wrapf(err, "GetVpc"))
return
}
peerVpc, err := peer.GetPeerVpc()
if err != nil {
self.taskFailed(ctx, peer, errors.Wrapf(err, "GetPeerVpc"))
return
}
iVpc, err := vpc.GetIVpc()
if err != nil {
self.taskFailed(ctx, peer, errors.Wrapf(err, "GetIVpc"))
return
}
iPeerVpc, err := peerVpc.GetIVpc()
if err != nil {
self.taskFailed(ctx, peer, errors.Wrapf(err, "GetIVpc"))
return
}
opts := &cloudprovider.VpcPeeringConnectionCreateOptions{
Name: peer.Name,
Desc: peer.Description,
Bandwidth: peer.Bandwidth,
PeerVpcId: iPeerVpc.GetId(),
PeerRegionId: iPeerVpc.GetRegion().GetId(),
PeerAccountId: iPeerVpc.GetAuthorityOwnerId(),
}
iPeerConnection, err := iVpc.CreateICloudVpcPeeringConnection(opts)
if err != nil {
self.taskFailed(ctx, peer, errors.Wrapf(err, "CreateICloudVpcPeeringConnection"))
return
}
err = iPeerVpc.AcceptICloudVpcPeeringConnection(iPeerConnection.GetGlobalId())
if err != nil {
self.taskFailed(ctx, peer, errors.Wrapf(err, "AcceptICloudVpcPeeringConnection"))
return
}
iPeerConnection.Refresh()
err = peer.SyncWithCloudPeerConnection(ctx, self.GetUserCred(), iPeerConnection, nil)
if err != nil {
self.taskFailed(ctx, peer, errors.Wrapf(err, "SyncWithCloudPeerConnection"))
return
}
self.taskComplete(ctx, peer)
}
func (self *VpcPeeringConnectionCreateTask) taskComplete(ctx context.Context, peer *models.SVpcPeeringConnection) {
logclient.AddActionLogWithStartable(self, peer, logclient.ACT_CREATE, nil, self.UserCred, true)
self.SetStageComplete(ctx, nil)
}
@@ -0,0 +1,89 @@
// 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 tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type VpcPeeringConnectionDeleteTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(VpcPeeringConnectionDeleteTask{})
}
func (self *VpcPeeringConnectionDeleteTask) taskFailed(ctx context.Context, peer *models.SVpcPeeringConnection, err error) {
peer.SetStatus(self.UserCred, api.VPC_PEERING_CONNECTION_STATUS_DELETE_FAILED, err.Error())
db.OpsLog.LogEvent(peer, db.ACT_DELOCATE_FAIL, err, self.UserCred)
logclient.AddActionLogWithStartable(self, peer, logclient.ACT_DELETE, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *VpcPeeringConnectionDeleteTask) taskComplete(ctx context.Context, peer *models.SVpcPeeringConnection) {
logclient.AddActionLogWithStartable(self, peer, logclient.ACT_DELETE, nil, self.UserCred, true)
peer.RealDelete(ctx, self.GetUserCred())
self.SetStageComplete(ctx, nil)
}
func (self *VpcPeeringConnectionDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
peer := obj.(*models.SVpcPeeringConnection)
vpc, err := peer.GetVpc()
if err != nil {
self.taskFailed(ctx, peer, errors.Wrapf(err, "GetVpc"))
return
}
iVpc, err := vpc.GetIVpc()
if err != nil {
self.taskFailed(ctx, peer, errors.Wrapf(err, "GetIVpc"))
return
}
if len(peer.ExternalId) == 0 {
self.taskComplete(ctx, peer)
return
}
iPeer, err := iVpc.GetICloudVpcPeeringConnectionById(peer.ExternalId)
if err != nil {
if errors.Cause(err) != cloudprovider.ErrNotFound {
self.taskFailed(ctx, peer, errors.Wrapf(err, "GetICloudVpcPeeringConnectionById(%s)", peer.ExternalId))
return
}
self.taskComplete(ctx, peer)
return
}
err = iPeer.Delete()
if err != nil {
self.taskFailed(ctx, peer, errors.Wrapf(err, "Delete"))
return
}
self.taskComplete(ctx, peer)
}
@@ -0,0 +1,79 @@
// 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 tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type VpcPeeringConnectionSyncstatusTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(VpcPeeringConnectionSyncstatusTask{})
}
func (self *VpcPeeringConnectionSyncstatusTask) taskFail(ctx context.Context, peer *models.SVpcPeeringConnection, err error) {
peer.SetStatus(self.UserCred, api.VPC_PEERING_CONNECTION_STATUS_UNKNOWN, err.Error())
db.OpsLog.LogEvent(peer, db.ACT_SYNC_STATUS, err, self.GetUserCred())
logclient.AddActionLogWithStartable(self, peer, logclient.ACT_SYNC_STATUS, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *VpcPeeringConnectionSyncstatusTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
peer := obj.(*models.SVpcPeeringConnection)
svpc, err := peer.GetVpc()
if err != nil {
self.taskFail(ctx, peer, errors.Wrap(err, "peer.GetVpc()"))
return
}
extVpc, err := svpc.GetIVpc()
if err != nil {
self.taskFail(ctx, peer, errors.Wrap(err, "svpc.GetIVpc()"))
return
}
ipeer, err := extVpc.GetICloudVpcPeeringConnectionById(peer.GetExternalId())
if err != nil {
self.taskFail(ctx, peer, errors.Wrapf(err, "extVpc.GetICloudVpcPeeringConnectionById(%s)", peer.GetExternalId()))
return
}
err = ipeer.Refresh()
if err != nil {
self.taskFail(ctx, peer, errors.Wrap(err, "ipeer.Refresh()"))
return
}
err = peer.SyncWithCloudPeerConnection(ctx, self.UserCred, ipeer, nil)
if err != nil {
self.taskFail(ctx, peer, errors.Wrapf(err, "SyncWithCloudPeerConnection(ctx, self.UserCred, %s, nil)", jsonutils.Marshal(ipeer).String()))
return
}
self.SetStageComplete(ctx, nil)
}
@@ -0,0 +1,29 @@
// 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 modules
import "yunion.io/x/onecloud/pkg/mcclient/modulebase"
var (
VpcPeeringConnections modulebase.ResourceManager
)
func init() {
VpcPeeringConnections = NewComputeManager("vpc_peering_connection", "vpc_peering_connections",
[]string{"ID", "Name", "Enabled", "Status", "vpc_id", "peer_vpc_id", "peer_account_id", "Public_Scope", "Domain_Id", "Domain"},
[]string{})
registerCompute(&VpcPeeringConnections)
}
@@ -0,0 +1,48 @@
// 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 options
import "yunion.io/x/jsonutils"
type VpcPeeringConnectionListOptions struct {
BaseListOptions
}
func (opts *VpcPeeringConnectionListOptions) Params() (jsonutils.JSONObject, error) {
return ListStructToParams(opts)
}
type VpcPeeringConnectionIdOptions struct {
ID string `json:"Vpc peering connection ID"`
}
func (opts *VpcPeeringConnectionIdOptions) GetId() string {
return opts.ID
}
func (opts *VpcPeeringConnectionIdOptions) Params() (jsonutils.JSONObject, error) {
return nil, nil
}
type VpcPeeringConnectionCreateOptions struct {
EnabledStatusCreateOptions
VpcId string
PeerVpcId string
Bandwidth int
}
func (opts *VpcPeeringConnectionCreateOptions) Params() (jsonutils.JSONObject, error) {
return jsonutils.Marshal(opts).(*jsonutils.JSONDict), nil
}
+12
View File
@@ -123,6 +123,18 @@ func (self *SAwsProviderFactory) GetSupportedDnsPolicyValues() map[cloudprovider
}
}
func (factory *SAwsProviderFactory) IsSupportCrossCloudEnvVpcPeering() bool {
return false
}
func (factory *SAwsProviderFactory) IsSupportCrossRegionVpcPeering() bool {
return true
}
func (factory *SAwsProviderFactory) IsSupportVpcPeeringVpcCidrOverlap() bool {
return false
}
func (self *SAwsProviderFactory) ValidateCreateCloudaccountData(ctx context.Context, userCred mcclient.TokenCredential, input cloudprovider.SCloudaccountCredential) (cloudprovider.SCloudaccount, error) {
output := cloudprovider.SCloudaccount{}
if len(input.AccessKeyId) == 0 {
+17 -8
View File
@@ -342,20 +342,29 @@ func (self *SRegion) fetchIVpcs() error {
self.ivpcs = make([]cloudprovider.ICloudVpc, 0)
for _, vpc := range vpcs.Vpcs {
cidrBlockAssociationSet := []string{}
for i := range vpc.CidrBlockAssociationSet {
cidr := vpc.CidrBlockAssociationSet[i]
if cidr.CidrBlockState.State != nil && *cidr.CidrBlockState.State == "associated" {
cidrBlockAssociationSet = append(cidrBlockAssociationSet, *cidr.CidrBlock)
}
}
tags := make(map[string]string, 0)
for _, tag := range vpc.Tags {
tags[*tag.Key] = *tag.Value
}
self.ivpcs = append(self.ivpcs, &SVpc{region: self,
CidrBlock: *vpc.CidrBlock,
Tags: tags,
IsDefault: *vpc.IsDefault,
RegionId: self.RegionId,
Status: *vpc.State,
VpcId: *vpc.VpcId,
VpcName: tags["Name"],
InstanceTenancy: *vpc.InstanceTenancy,
CidrBlock: *vpc.CidrBlock,
CidrBlockAssociationSet: cidrBlockAssociationSet,
Tags: tags,
IsDefault: *vpc.IsDefault,
RegionId: self.RegionId,
Status: *vpc.State,
VpcId: *vpc.VpcId,
VpcName: tags["Name"],
InstanceTenancy: *vpc.InstanceTenancy,
})
}
+32 -8
View File
@@ -23,11 +23,17 @@ import (
type SRoute struct {
routetable *SRouteTable
DestinationCIDRBlock string `json:"DestinationCidrBlock"`
GatewayID *string `json:"GatewayId,omitempty"`
Origin string `json:"Origin"`
State string `json:"State"`
NatGatewayID *string `json:"NatGatewayId,omitempty"`
DestinationCIDRBlock string `json:"DestinationCidrBlock"`
Origin string `json:"Origin"`
State string `json:"State"`
// only one exist
GatewayID *string `json:"GatewayId,omitempty"`
NatGatewayID *string `json:"NatGatewayId,omitempty"`
InstanceID *string `json:"InstanceId,omitempty"`
LocalGatewayID *string `json:"LocalGatewayId,omitempty"`
NetworkInterfaceID *string `json:"NetworkInterfaceId,omitempty"`
TransitGatewayID *string `json:"TransitGatewayId,omitempty"`
VpcPeeringConnectionID *string `json:"VpcPeeringConnectionId,omitempty"`
}
func (self *SRoute) GetType() string {
@@ -69,9 +75,27 @@ func (self *SRoute) GetNextHopType() string {
}
func (self *SRoute) GetNextHop() string {
if self.GatewayID == nil {
return ""
if self.NatGatewayID != nil {
return *self.NatGatewayID
}
if self.GatewayID != nil {
return *self.GatewayID
}
if self.InstanceID != nil {
return *self.InstanceID
}
if self.LocalGatewayID != nil {
return *self.LocalGatewayID
}
if self.NetworkInterfaceID != nil {
return *self.NetworkInterfaceID
}
if self.TransitGatewayID != nil {
return *self.TransitGatewayID
}
if self.VpcPeeringConnectionID != nil {
return *self.VpcPeeringConnectionID
}
return *self.GatewayID
return ""
}
+45
View File
@@ -15,6 +15,9 @@
package aws
import (
"fmt"
"strings"
"github.com/aws/aws-sdk-go/service/ec2"
"yunion.io/x/jsonutils"
@@ -135,6 +138,48 @@ func (self *SRegion) GetRouteTables(vpcId string, mainRouteOnly bool) ([]SRouteT
return routeTables, nil
}
func (self *SRegion) CreateRoute(routeTableId string, DestinationCIDRBlock string, targetId string) error {
input := &ec2.CreateRouteInput{}
input.RouteTableId = &routeTableId
input.DestinationCidrBlock = &DestinationCIDRBlock
segs := strings.Split(targetId, "-")
if len(segs) == 0 {
return fmt.Errorf("invalid aws vpc targetid:%s", targetId)
}
switch segs[0] {
case "i":
input.InstanceId = &targetId
case "igw", "vgw":
input.GatewayId = &targetId
case "pcx":
input.VpcPeeringConnectionId = &targetId
case "eni":
input.NetworkInterfaceId = &targetId
case "nat":
input.NatGatewayId = &targetId
case "eigw":
input.EgressOnlyInternetGatewayId = &targetId
default:
return fmt.Errorf("invalid aws vpc targetid:%s", targetId)
}
_, err := self.ec2Client.CreateRoute(input)
if err != nil {
return errors.Wrapf(err, "self.ec2Client.CreateRoute(%s)", jsonutils.Marshal(input).String())
}
return nil
}
func (self *SRegion) RemoveRoute(routeTableId string, DestinationCIDRBlock string) error {
input := &ec2.DeleteRouteInput{}
input.RouteTableId = &routeTableId
input.DestinationCidrBlock = &DestinationCIDRBlock
_, err := self.ec2Client.DeleteRoute(input)
if err != nil {
return errors.Wrapf(err, "self.ec2Client.DeleteRoute(%s)", jsonutils.Marshal(input).String())
}
return nil
}
func (self *SRegion) GetRouteTablesByNetworkId(netId string) ([]SRouteTable, error) {
input := &ec2.DescribeRouteTablesInput{}
filter := &ec2.Filter{}
+16 -2
View File
@@ -21,10 +21,11 @@ import (
func init() {
type RouteTableListOptions struct {
VpcId string `help:"vpc id"`
VpcId string `help:"vpc id"`
MainOnly bool
}
shellutils.R(&RouteTableListOptions{}, "routetable-list", "List route tables", func(cli *aws.SRegion, args *RouteTableListOptions) error {
routetables, err := cli.GetRouteTables(args.VpcId, false)
routetables, err := cli.GetRouteTables(args.VpcId, args.MainOnly)
if err != nil {
printObject(err)
return nil
@@ -33,4 +34,17 @@ func init() {
printList(routetables, 0, 0, 0, nil)
return nil
})
type RouteCreateOptions struct {
ROUTETABLEID string `help:"routetable id"`
CIDRBLOCK string
TARGETID string
}
shellutils.R(&RouteCreateOptions{}, "route-create", "create route", func(cli *aws.SRegion, args *RouteCreateOptions) error {
err := cli.CreateRoute(args.ROUTETABLEID, args.CIDRBLOCK, args.TARGETID)
if err != nil {
return err
}
return nil
})
}
+84
View File
@@ -15,6 +15,7 @@
package shell
import (
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud/aws"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
@@ -32,4 +33,87 @@ func init() {
printList(vpcs, total, args.Offset, args.Limit, []string{})
return nil
})
type VpcPeeringConnectionListOptions struct {
VPCID string
}
shellutils.R(&VpcPeeringConnectionListOptions{}, "vpc-peering-connection-list", "List vpcPeeringConnections", func(cli *aws.SRegion, args *VpcPeeringConnectionListOptions) error {
vpcPCs, err := cli.DescribeVpcPeeringConnections(args.VPCID)
if err != nil {
return err
}
printList(vpcPCs, len(vpcPCs), len(vpcPCs), len(vpcPCs), []string{})
return nil
})
type VpcPeeringConnectionShowOptions struct {
ID string
}
shellutils.R(&VpcPeeringConnectionShowOptions{}, "vpc-peering-connection-show", "show vpcPeeringConnections", func(cli *aws.SRegion, args *VpcPeeringConnectionShowOptions) error {
vpcPC, err := cli.GetVpcPeeringConnectionById(args.ID)
if err != nil {
return err
}
printObject(vpcPC)
return nil
})
type VpcPeeringConnectionCreateOptions struct {
NAME string
VPCID string
PEERVPCID string
PEERACCOUNTID string
PEERREGIONID string
Desc string
}
shellutils.R(&VpcPeeringConnectionCreateOptions{}, "vpc-peering-connection-create", "create vpcPeeringConnection", func(cli *aws.SRegion, args *VpcPeeringConnectionCreateOptions) error {
opts := cloudprovider.VpcPeeringConnectionCreateOptions{}
opts.Desc = args.Desc
opts.Name = args.NAME
opts.PeerAccountId = args.PEERACCOUNTID
opts.PeerRegionId = args.PEERREGIONID
opts.PeerVpcId = args.PEERVPCID
vpcPC, err := cli.CreateVpcPeeringConnection(args.VPCID, &opts)
if err != nil {
return err
}
printObject(vpcPC)
return nil
})
type VpcPeeringConnectionAcceptOptions struct {
ID string
}
shellutils.R(&VpcPeeringConnectionAcceptOptions{}, "vpc-peering-connection-accept", "accept vpcPeeringConnection", func(cli *aws.SRegion, args *VpcPeeringConnectionAcceptOptions) error {
vpcPC, err := cli.AcceptVpcPeeringConnection(args.ID)
if err != nil {
return err
}
printObject(vpcPC)
return nil
})
type VpcPeeringConnectionDeleteOptions struct {
ID string
}
shellutils.R(&VpcPeeringConnectionDeleteOptions{}, "vpc-peering-connection-delete", "delete vpcPeeringConnection", func(cli *aws.SRegion, args *VpcPeeringConnectionDeleteOptions) error {
err := cli.DeleteVpcPeeringConnection(args.ID)
if err != nil {
return err
}
return nil
})
type VpcPeeringConnectionRouteDeleteOptions struct {
ID string
}
shellutils.R(&VpcPeeringConnectionAcceptOptions{}, "vpc-peering-connection-route-delete", "delete vpc-peering-connection route", func(cli *aws.SRegion, args *VpcPeeringConnectionAcceptOptions) error {
err := cli.DeleteVpcPeeringConnectionRoute(args.ID)
if err != nil {
printObject(err)
return err
}
return nil
})
}
+127 -1
View File
@@ -17,10 +17,12 @@ package aws
import (
"fmt"
"strings"
"time"
"github.com/aws/aws-sdk-go/service/ec2"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
@@ -218,6 +220,130 @@ func (self *SVpc) fetchSecurityGroups() error {
return nil
}
func (self *SVpc) GetICloudVpcPeeringConnections() ([]cloudprovider.ICloudVpcPeeringConnection, error) {
svpcPCs, err := self.getRequesterVpcPeeringConnections()
if err != nil {
return nil, errors.Wrap(err, "self.getSVpcPeeringConnections()")
}
ret := []cloudprovider.ICloudVpcPeeringConnection{}
for i := range svpcPCs {
ret = append(ret, svpcPCs[i])
}
return ret, nil
}
func (self *SVpc) GetICloudVpcPeeringConnectionById(id string) (cloudprovider.ICloudVpcPeeringConnection, error) {
vpcPc, err := self.getSVpcPeeringConnectionById(id)
if err != nil {
return nil, errors.Wrapf(err, "getSVpcPeeringConnectionById(%s)", id)
}
return vpcPc, nil
}
func (self *SVpc) CreateICloudVpcPeeringConnection(opts *cloudprovider.VpcPeeringConnectionCreateOptions) (cloudprovider.ICloudVpcPeeringConnection, error) {
return self.createSVpcPeeringConnection(opts)
}
func (self *SVpc) AcceptICloudVpcPeeringConnection(id string) error {
return self.acceptSVpcPeeringConnection(id)
}
func (self *SVpc) GetAuthorityOwnerId() string {
identity, err := self.region.client.GetCallerIdentity()
if err != nil {
log.Errorf(err.Error() + "self.region.client.GetCallerIdentity()")
return ""
}
return identity.Account
}
func (self *SVpc) getSVpcPeeringConnectionById(id string) (*SVpcPeeringConnection, error) {
vpcPC, err := self.region.GetVpcPeeringConnectionById(id)
if err != nil {
return nil, errors.Wrapf(err, "self.region.GetVpcPeeringConnectionById(%s)", id)
}
if vpcPC.Status.Code != nil && (*vpcPC.Status.Code == ec2.VpcPeeringConnectionStateReasonCodeDeleted ||
*vpcPC.Status.Code == ec2.VpcPeeringConnectionStateReasonCodeDeleting) {
return nil, cloudprovider.ErrNotFound
}
svpcPC := SVpcPeeringConnection{}
svpcPC.vpc = self
svpcPC.vpcPC = vpcPC
return &svpcPC, nil
}
func (self *SVpc) getRequesterVpcPeeringConnections() ([]*SVpcPeeringConnection, error) {
vpcPCs, err := self.region.DescribeRequesterVpcPeeringConnections(self.VpcId)
if err != nil {
return nil, errors.Wrap(err, "self.region.DescribeVpcPeeringConnections()")
}
ivpcPCs := []*SVpcPeeringConnection{}
for i := range vpcPCs {
if vpcPCs[i].Status.Code != nil && (*vpcPCs[i].Status.Code == ec2.VpcPeeringConnectionStateReasonCodeDeleted ||
*vpcPCs[i].Status.Code == ec2.VpcPeeringConnectionStateReasonCodeDeleting) {
continue
}
svpcPC := SVpcPeeringConnection{}
svpcPC.vpc = self
svpcPC.vpcPC = vpcPCs[i]
ivpcPCs = append(ivpcPCs, &svpcPC)
}
return ivpcPCs, nil
}
func (self *SVpc) createSVpcPeeringConnection(opts *cloudprovider.VpcPeeringConnectionCreateOptions) (*SVpcPeeringConnection, error) {
svpcPC := SVpcPeeringConnection{}
vpcPC, err := self.region.CreateVpcPeeringConnection(self.VpcId, opts)
if err != nil {
return nil, errors.Wrapf(err, " self.region.CreateVpcPeeringConnection(%s,%s)", self.VpcId, jsonutils.Marshal(opts).String())
}
svpcPC.vpc = self
svpcPC.vpcPC = vpcPC
err = cloudprovider.WaitMultiStatus(&svpcPC, []string{api.VPC_PEERING_CONNECTION_STATUS_PENDING_ACCEPT,
api.VPC_PEERING_CONNECTION_STATUS_ACTIVE,
api.VPC_PEERING_CONNECTION_STATUS_DELETING}, 5*time.Second, 60*time.Second)
if err != nil {
return nil, errors.Wrap(err, "cloudprovider.WaitMultiStatus")
}
if svpcPC.GetStatus() == api.VPC_PEERING_CONNECTION_STATUS_DELETING {
return nil, errors.Wrapf(cloudprovider.ErrInvalidStatus, "vpcpeeringconnection:%s invalidate status", jsonutils.Marshal(svpcPC.vpcPC).String())
}
return &svpcPC, nil
}
func (self *SVpc) acceptSVpcPeeringConnection(id string) error {
svpcPC, err := self.getSVpcPeeringConnectionById(id)
if err != nil {
return errors.Wrapf(err, "self.getSVpcPeeringConnectionById(%s)", id)
}
// 其他region 创建的连接请求,有短暂的provisioning状态
err = cloudprovider.WaitMultiStatus(svpcPC, []string{api.VPC_PEERING_CONNECTION_STATUS_ACTIVE,
api.VPC_PEERING_CONNECTION_STATUS_PENDING_ACCEPT,
api.VPC_PEERING_CONNECTION_STATUS_DELETING}, 5*time.Second, 60*time.Second)
if err != nil {
return errors.Wrap(err, "cloudprovider.WaitMultiStatus")
}
if svpcPC.GetStatus() == api.VPC_PEERING_CONNECTION_STATUS_DELETING {
return errors.Wrapf(cloudprovider.ErrInvalidStatus, "vpcpeeringconnection:%s invalidate status", jsonutils.Marshal(svpcPC.vpcPC).String())
}
if svpcPC.GetStatus() == api.VPC_PEERING_CONNECTION_STATUS_PENDING_ACCEPT {
_, err := self.region.AcceptVpcPeeringConnection(id)
if err != nil {
return errors.Wrapf(err, "self.region.AcceptVpcPeeringConnection(%s)", id)
}
}
err = cloudprovider.WaitMultiStatus(svpcPC, []string{api.VPC_PEERING_CONNECTION_STATUS_ACTIVE,
api.VPC_PEERING_CONNECTION_STATUS_DELETING}, 5*time.Second, 60*time.Second)
if err != nil {
return errors.Wrap(err, "cloudprovider.WaitMultiStatus")
}
if svpcPC.GetStatus() == api.VPC_PEERING_CONNECTION_STATUS_DELETING {
return errors.Wrapf(cloudprovider.ErrInvalidStatus, "vpcpeeringconnection:%s invalidate status", jsonutils.Marshal(svpcPC.vpcPC).String())
}
return nil
}
func (self *SRegion) getVpc(vpcId string) (*SVpc, error) {
if len(vpcId) == 0 {
return nil, fmt.Errorf("GetVpc vpc id should not be empty.")
@@ -299,7 +425,7 @@ func (self *SRegion) GetVpcs(vpcId []string, offset int, limit int) ([]SVpc, int
cidrBlockAssociationSet := []string{}
for i := range item.CidrBlockAssociationSet {
cidr := item.CidrBlockAssociationSet[i]
if *cidr.CidrBlockState.State == "associated" {
if cidr.CidrBlockState.State != nil && *cidr.CidrBlockState.State == "associated" {
cidrBlockAssociationSet = append(cidrBlockAssociationSet, *cidr.CidrBlock)
}
}
@@ -0,0 +1,287 @@
// 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 (
"github.com/aws/aws-sdk-go/service/ec2"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud"
)
func (self *SRegion) DescribeVpcPeeringConnections(vpcId string) ([]*ec2.VpcPeeringConnection, error) {
result := []*ec2.VpcPeeringConnection{}
requestvpcPCs, err := self.DescribeRequesterVpcPeeringConnections(vpcId)
if err != nil {
return nil, errors.Wrapf(err, "self.DescribeRequesterVpcPeeringConnections(%s)", vpcId)
}
result = append(result, requestvpcPCs...)
acceptvpcPCs, err := self.DescribeAccepterVpcPeeringConnections(vpcId)
if err != nil {
return nil, errors.Wrapf(err, "self.DescribeRequesterVpcPeeringConnections(%s)", vpcId)
}
result = append(result, acceptvpcPCs...)
return result, nil
}
func (self *SRegion) DescribeRequesterVpcPeeringConnections(vpcId string) ([]*ec2.VpcPeeringConnection, error) {
params := ec2.DescribeVpcPeeringConnectionsInput{}
result := []*ec2.VpcPeeringConnection{}
var maxResult int64 = 20
params.MaxResults = &maxResult
filter := ec2.Filter{}
filter.Values = []*string{&vpcId}
// request peeringConnection
filterName := "requester-vpc-info.vpc-id"
filter.Name = &filterName
params.Filters = []*ec2.Filter{&filter}
for {
ret, err := self.ec2Client.DescribeVpcPeeringConnections(&params)
if err != nil {
return nil, errors.Wrapf(err, "self.ec2Client.DescribeVpcPeeringConnections(%s)", jsonutils.Marshal(params).String())
}
result = append(result, ret.VpcPeeringConnections...)
if ret.NextToken == nil {
break
}
params.NextToken = ret.NextToken
}
return result, nil
}
func (self *SRegion) DescribeAccepterVpcPeeringConnections(vpcId string) ([]*ec2.VpcPeeringConnection, error) {
params := ec2.DescribeVpcPeeringConnectionsInput{}
result := []*ec2.VpcPeeringConnection{}
var maxResult int64 = 20
params.MaxResults = &maxResult
filter := ec2.Filter{}
filter.Values = []*string{&vpcId}
// accept peeringConnection
filterName := "accepter-vpc-info.vpc-id"
filter.Name = &filterName
params.Filters = []*ec2.Filter{&filter}
for {
ret, err := self.ec2Client.DescribeVpcPeeringConnections(&params)
if err != nil {
return nil, errors.Wrapf(err, "self.ec2Client.DescribeVpcPeeringConnections(%s)", jsonutils.Marshal(params).String())
}
result = append(result, ret.VpcPeeringConnections...)
if ret.NextToken == nil {
break
}
params.NextToken = ret.NextToken
}
return result, nil
}
func (self *SRegion) GetVpcPeeringConnectionById(Id string) (*ec2.VpcPeeringConnection, error) {
params := ec2.DescribeVpcPeeringConnectionsInput{}
result := []*ec2.VpcPeeringConnection{}
var maxResult int64 = 20
params.MaxResults = &maxResult
filter := ec2.Filter{}
filter.Values = []*string{&Id}
filterName := "vpc-peering-connection-id"
filter.Name = &filterName
params.Filters = []*ec2.Filter{&filter}
for {
ret, err := self.ec2Client.DescribeVpcPeeringConnections(&params)
if err != nil {
return nil, errors.Wrapf(err, "self.ec2Client.DescribeVpcPeeringConnections(%s)", jsonutils.Marshal(params).String())
}
result = append(result, ret.VpcPeeringConnections...)
if ret.NextToken == nil {
break
}
params.NextToken = ret.NextToken
}
if len(result) < 1 {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "GetVpcPeeringConnectionById(%s)", Id)
}
if len(result) > 1 {
return nil, errors.Wrapf(cloudprovider.ErrDuplicateId, "GetVpcPeeringConnectionById(%s)", Id)
}
return result[0], nil
}
func (self *SRegion) CreateVpcPeeringConnection(vpcId string, opts *cloudprovider.VpcPeeringConnectionCreateOptions) (*ec2.VpcPeeringConnection, error) {
params := ec2.CreateVpcPeeringConnectionInput{}
params.VpcId = &vpcId
params.PeerVpcId = &opts.PeerVpcId
params.PeerRegion = &opts.PeerRegionId
params.PeerOwnerId = &opts.PeerAccountId
ret, err := self.ec2Client.CreateVpcPeeringConnection(&params)
if err != nil {
return nil, errors.Wrapf(err, "self.ec2Client.CreateVpcPeeringConnection(%s)", jsonutils.Marshal(params).String())
}
// add tags
tagParams := ec2.CreateTagsInput{}
tagParams.Resources = []*string{ret.VpcPeeringConnection.VpcPeeringConnectionId}
nametag := "Name"
desctag := "Description"
tagParams.Tags = []*ec2.Tag{{Key: &nametag, Value: &opts.Name}, {Key: &desctag, Value: &opts.Desc}}
_, err = self.ec2Client.CreateTags(&tagParams)
if err != nil {
return nil, errors.Wrapf(err, "self.ec2Client.CreateTags(%s)", jsonutils.Marshal(tagParams).String())
}
ret.VpcPeeringConnection.Tags = tagParams.Tags
return ret.VpcPeeringConnection, nil
}
func (self *SRegion) DeleteVpcPeeringConnection(vpcPeeringConnectionId string) error {
params := ec2.DeleteVpcPeeringConnectionInput{}
params.VpcPeeringConnectionId = &vpcPeeringConnectionId
_, err := self.ec2Client.DeleteVpcPeeringConnection(&params)
if err != nil {
return errors.Wrapf(err, "self.ec2Client.DeleteVpcPeeringConnection(%s)", jsonutils.Marshal(params).String())
}
return nil
}
func (self *SRegion) AcceptVpcPeeringConnection(vpcPeeringConnectionId string) (*ec2.VpcPeeringConnection, error) {
params := ec2.AcceptVpcPeeringConnectionInput{}
params.VpcPeeringConnectionId = &vpcPeeringConnectionId
ret, err := self.ec2Client.AcceptVpcPeeringConnection(&params)
if err != nil {
return nil, errors.Wrapf(err, "self.ec2Client.AcceptVpcPeeringConnection(%s)", jsonutils.Marshal(params).String())
}
return ret.VpcPeeringConnection, nil
}
func (self *SRegion) DeleteVpcPeeringConnectionRoute(vpcPeeringConnectionId string) error {
input := &ec2.DescribeRouteTablesInput{}
filters := make([]*ec2.Filter, 0)
filters = AppendSingleValueFilter(filters, "association.main", "true")
filters = AppendSingleValueFilter(filters, "route.vpc-peering-connection-id", vpcPeeringConnectionId)
input.SetFilters(filters)
routeTables := []*ec2.RouteTable{}
for {
ret, err := self.ec2Client.DescribeRouteTables(input)
if err != nil {
return errors.Wrap(err, "SRegion.GetRouteTables.DescribeRouteTables")
}
routeTables = append(routeTables, ret.RouteTables...)
input.NextToken = ret.NextToken
if ret.NextToken == nil {
break
}
}
for i := range routeTables {
if routeTables[i] != nil && routeTables[i].RouteTableId != nil && routeTables[i].Routes != nil {
for j := range routeTables[i].Routes {
if routeTables[i].Routes[j] != nil &&
routeTables[i].Routes[j].VpcPeeringConnectionId != nil &&
*routeTables[i].Routes[j].VpcPeeringConnectionId == vpcPeeringConnectionId &&
routeTables[i].Routes[j].DestinationCidrBlock != nil {
err := self.RemoveRoute(*routeTables[i].RouteTableId, *routeTables[i].Routes[j].DestinationCidrBlock)
if err != nil {
return errors.Wrapf(err, "self.RemoveRoute(%s,%s)", *routeTables[i].RouteTableId, *routeTables[i].Routes[j].DestinationCidrBlock)
}
}
}
}
}
return nil
}
type SVpcPeeringConnection struct {
multicloud.SResourceBase
vpc *SVpc
vpcPC *ec2.VpcPeeringConnection
}
func (self *SVpcPeeringConnection) GetId() string {
if self.vpcPC.VpcPeeringConnectionId != nil {
return *self.vpcPC.VpcPeeringConnectionId
}
return ""
}
// tags?
func (self *SVpcPeeringConnection) GetName() string {
for i := range self.vpcPC.Tags {
if self.vpcPC.Tags[i] != nil && self.vpcPC.Tags[i].Key != nil &&
*self.vpcPC.Tags[i].Key == "Name" && self.vpcPC.Tags[i].Value != nil {
return *self.vpcPC.Tags[i].Value
}
}
return self.GetId()
}
func (self *SVpcPeeringConnection) GetGlobalId() string {
return self.GetId()
}
func (self *SVpcPeeringConnection) GetStatus() string {
if self.vpcPC.Status.Code != nil {
switch *self.vpcPC.Status.Code {
case ec2.VpcPeeringConnectionStateReasonCodeInitiatingRequest, ec2.VpcPeeringConnectionStateReasonCodeProvisioning:
return api.VPC_PEERING_CONNECTION_STATUS_CREATING
case ec2.VpcPeeringConnectionStateReasonCodePendingAcceptance:
return api.VPC_PEERING_CONNECTION_STATUS_PENDING_ACCEPT
case ec2.VpcPeeringConnectionStateReasonCodeActive:
return api.VPC_PEERING_CONNECTION_STATUS_ACTIVE
case ec2.VpcPeeringConnectionStateReasonCodeDeleted, ec2.VpcPeeringConnectionStateReasonCodeDeleting:
return api.VPC_PEERING_CONNECTION_STATUS_DELETING
default:
return api.VPC_PEERING_CONNECTION_STATUS_UNKNOWN
}
}
return api.VPC_PEERING_CONNECTION_STATUS_UNKNOWN
}
func (self *SVpcPeeringConnection) Refresh() error {
vpcPC, err := self.vpc.region.GetVpcPeeringConnectionById(self.GetId())
if err != nil {
return errors.Wrapf(err, "self.vpc.region.GetVpcPeeringConnectionById(%s)", self.GetId())
}
self.vpcPC = vpcPC
return nil
}
func (self *SVpcPeeringConnection) GetPeerVpcId() string {
if self.vpcPC.AccepterVpcInfo != nil {
if self.vpcPC.AccepterVpcInfo.VpcId != nil {
return *self.vpcPC.AccepterVpcInfo.VpcId
}
}
return ""
}
func (self *SVpcPeeringConnection) GetPeerAccountId() string {
if self.vpcPC.AccepterVpcInfo != nil {
if self.vpcPC.AccepterVpcInfo.OwnerId != nil {
return *self.vpcPC.AccepterVpcInfo.OwnerId
}
}
return ""
}
func (self *SVpcPeeringConnection) Delete() error {
err := self.vpc.region.DeleteVpcPeeringConnection(self.GetId())
if err != nil {
return errors.Wrapf(err, "self.region.DeleteVpcPeeringConnection(%s)", self.GetId())
}
return nil
}
func (self *SVpcPeeringConnection) GetEnabled() bool {
return true
}
+5 -2
View File
@@ -15,8 +15,11 @@
package multicloud
import (
"fmt"
"time"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
type SBillingBase struct{}
@@ -34,7 +37,7 @@ func (self *SBillingBase) GetExpiredAt() time.Time {
}
func (self *SBillingBase) SetAutoRenew(autoRenew bool) error {
return fmt.Errorf("Not Implement SetAutoRenew")
return errors.Wrapf(cloudprovider.ErrNotImplemented, "SetAutoRenew")
}
func (self *SBillingBase) IsAutoRenew() bool {
+5 -5
View File
@@ -28,7 +28,7 @@
package multicloud
import (
"fmt"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
@@ -42,17 +42,17 @@ func (account *SDBInstanceAccountBase) GetIDBInstanceAccountPrivileges() ([]clou
}
func (account *SDBInstanceAccountBase) Delete() error {
return fmt.Errorf("Not Implemented Delete")
return errors.Wrapf(cloudprovider.ErrNotImplemented, "Delete")
}
func (account *SDBInstanceAccountBase) ResetPassword(password string) error {
return fmt.Errorf("Not Implemented ResetPassword")
return errors.Wrapf(cloudprovider.ErrNotImplemented, "ResetPassword")
}
func (backup *SDBInstanceAccountBase) GrantPrivilege(database, privilege string) error {
return fmt.Errorf("Not Implement GrantPrivilege")
return errors.Wrapf(cloudprovider.ErrNotImplemented, "GrantPrivilege")
}
func (backup *SDBInstanceAccountBase) RevokePrivilege(database string) error {
return fmt.Errorf("Not Implement RevokePrivilege")
return errors.Wrapf(cloudprovider.ErrNotImplemented, "RevokePrivilege")
}
+3 -2
View File
@@ -15,9 +15,10 @@
package multicloud
import (
"fmt"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
type SDBInstanceBackupBase struct {
@@ -29,7 +30,7 @@ func (backup *SDBInstanceBackupBase) GetBackMode() string {
}
func (backup *SDBInstanceBackupBase) Delete() error {
return fmt.Errorf("Not Implement Delete")
return errors.Wrapf(cloudprovider.ErrNotImplemented, "Delete")
}
func (backup *SDBInstanceBackupBase) GetProjectId() string {
+17 -16
View File
@@ -16,7 +16,8 @@ package multicloud
import (
"context"
"fmt"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/util/billing"
@@ -36,23 +37,23 @@ func (instance *SDBInstanceBase) GetInternalConnectionStr() string {
}
func (instance *SDBInstanceBase) GetDBNetwork() (*cloudprovider.SDBInstanceNetwork, error) {
return nil, fmt.Errorf("Not Implemented GetDBNetwork")
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetDBNetwork")
}
func (instance *SDBInstanceBase) GetIDBInstanceParameters() ([]cloudprovider.ICloudDBInstanceParameter, error) {
return nil, fmt.Errorf("Not Implemented GetIDBInstanceParameters")
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetIDBInstanceParameters")
}
func (instance *SDBInstanceBase) GetIDBInstanceDatabases() ([]cloudprovider.ICloudDBInstanceDatabase, error) {
return nil, fmt.Errorf("Not Implemented GetIDBInstanceDatabases")
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetIDBInstanceDatabases")
}
func (instance *SDBInstanceBase) GetIDBInstanceAccounts() ([]cloudprovider.ICloudDBInstanceAccount, error) {
return nil, fmt.Errorf("Not Implemented GetIDBInstanceAccounts")
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetIDBInstanceAccounts")
}
func (instance *SDBInstanceBase) GetIDBInstanceBackups() ([]cloudprovider.ICloudDBInstanceBackup, error) {
return nil, fmt.Errorf("Not Implemented GetIDBInstanceBackups")
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetIDBInstanceBackups")
}
func (instance *SDBInstanceBase) GetCategory() string {
@@ -60,11 +61,11 @@ func (instance *SDBInstanceBase) GetCategory() string {
}
func (instance *SDBInstanceBase) Reboot() error {
return fmt.Errorf("Not Implemmented Reboot")
return errors.Wrapf(cloudprovider.ErrNotImplemented, "Reboot")
}
func (instance *SDBInstanceBase) Delete() error {
return fmt.Errorf("Not Implemmented Delete")
return errors.Wrapf(cloudprovider.ErrNotImplemented, "Delete")
}
func (instance *SDBInstanceBase) GetMasterInstanceId() string {
@@ -76,33 +77,33 @@ func (instance *SDBInstanceBase) GetSecurityGroupId() string {
}
func (instance *SDBInstanceBase) Renew(bc billing.SBillingCycle) error {
return fmt.Errorf("Not Implemented Renew")
return errors.Wrapf(cloudprovider.ErrNotImplemented, "Renew")
}
func (instance *SDBInstanceBase) ChangeConfig(ctx context.Context, config *cloudprovider.SManagedDBInstanceChangeConfig) error {
return fmt.Errorf("Not Implemented ChnageConfig")
return errors.Wrapf(cloudprovider.ErrNotImplemented, "ChangeConfig")
}
func (instance *SDBInstanceBase) OpenPublicConnection() error {
return fmt.Errorf("Not Implemented OpenPublicConnection")
return errors.Wrapf(cloudprovider.ErrNotImplemented, "OpenPublicConnection")
}
func (instance *SDBInstanceBase) ClosePublicConnection() error {
return fmt.Errorf("Not Implemented ClosePublicConnection")
return errors.Wrapf(cloudprovider.ErrNotImplemented, "ClosePublicConnection")
}
func (instance *SDBInstanceBase) CreateDatabase(conf *cloudprovider.SDBInstanceDatabaseCreateConfig) error {
return fmt.Errorf("Not Implemented CreateDatabase")
return errors.Wrapf(cloudprovider.ErrNotImplemented, "CreateDatabase")
}
func (instance *SDBInstanceBase) CreateAccount(conf *cloudprovider.SDBInstanceAccountCreateConfig) error {
return fmt.Errorf("Not Implemented CreateAccount")
return errors.Wrapf(cloudprovider.ErrNotImplemented, "CreateAccount")
}
func (instance *SDBInstanceBase) CreateIBackup(conf *cloudprovider.SDBInstanceBackupCreateConfig) (string, error) {
return "", fmt.Errorf("Not Implemented CreateIBackup")
return "", errors.Wrapf(cloudprovider.ErrNotImplemented, "CreateIBackup")
}
func (instance *SDBInstanceBase) RecoveryFromBackup(conf *cloudprovider.SDBInstanceRecoveryConfig) error {
return fmt.Errorf("Not Implemented RecoveryFromBackup")
return errors.Wrapf(cloudprovider.ErrNotImplemented, "RecoveryFromBackup")
}
+6 -2
View File
@@ -14,12 +14,16 @@
package multicloud
import "fmt"
import (
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
type SDBInstanceDatabaseBase struct {
SResourceBase
}
func (db *SDBInstanceDatabaseBase) Delete() error {
return fmt.Errorf("Not Implemented Delete")
return errors.Wrapf(cloudprovider.ErrNotImplemented, "Delete")
}
+2
View File
@@ -76,6 +76,7 @@ type Client struct {
SNatRules *modules.SNatSRuleManager
DNatRules *modules.SNatDRuleManager
NatGateways *modules.SNatGatewayManager
VpcPeerings *modules.SVpcPeeringManager
DBInstance *modules.SDBInstanceManager
DBInstanceBackup *modules.SDBInstanceBackupManager
DBInstanceFlavor *modules.SDBInstanceFlavorManager
@@ -214,6 +215,7 @@ func (self *Client) initManagers() {
self.SNatRules = modules.NewNatSManager(self.regionId, self.projectId, self.signer, self.debug)
self.DNatRules = modules.NewNatDManager(self.regionId, self.projectId, self.signer, self.debug)
self.NatGateways = modules.NewNatGatewayManager(self.regionId, self.projectId, self.signer, self.debug)
self.VpcPeerings = modules.NewVpcPeeringManager(self.regionId, self.projectId, self.signer, self.debug)
self.DBInstance = modules.NewDBInstanceManager(self.regionId, self.projectId, self.signer, self.debug)
self.DBInstanceBackup = modules.NewDBInstanceBackupManager(self.regionId, self.projectId, self.signer, self.debug)
self.DBInstanceFlavor = modules.NewDBInstanceFlavorManager(self.regionId, self.projectId, self.signer, self.debug)
@@ -0,0 +1,37 @@
// 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 modules
import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
)
type SVpcPeeringManager struct {
SResourceManager
}
func NewVpcPeeringManager(regionId string, projectId string, signer auth.Signer, debug bool) *SVpcPeeringManager {
return &SVpcPeeringManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
ServiceName: ServiceNameVPC,
Region: regionId,
ProjectId: "",
version: "v2.0",
Keyword: "peering",
KeywordPlural: "peerings",
ResourceKeyword: "vpc/peerings",
}}
}
@@ -64,6 +64,18 @@ func (self *SHuaweiProviderFactory) IsSupportCreateCloudgroup() bool {
return true
}
func (factory *SHuaweiProviderFactory) IsSupportCrossCloudEnvVpcPeering() bool {
return false
}
func (factory *SHuaweiProviderFactory) IsSupportCrossRegionVpcPeering() bool {
return false
}
func (factory *SHuaweiProviderFactory) IsSupportVpcPeeringVpcCidrOverlap() bool {
return true
}
func (self *SHuaweiProviderFactory) ValidateCreateCloudaccountData(ctx context.Context, userCred mcclient.TokenCredential, input cloudprovider.SCloudaccountCredential) (cloudprovider.SCloudaccount, error) {
output := cloudprovider.SCloudaccount{}
if len(input.AccessKeyId) == 0 {
+31 -4
View File
@@ -70,7 +70,7 @@ type SRouteTable struct {
VpcId string
Description string
Type string
Routes []cloudprovider.ICloudRoute
Routes []*SRouteEntry
}
func NewSRouteTable(vpc *SVpc, Type string) SRouteTable {
@@ -134,7 +134,11 @@ func (self *SRouteTable) GetIRoutes() ([]cloudprovider.ICloudRoute, error) {
return nil, err
}
}
return self.Routes, nil
ret := []cloudprovider.ICloudRoute{}
for i := range self.Routes {
ret = append(ret, self.Routes[i])
}
return ret, nil
}
// fetchRoutes fetch Routes
@@ -152,7 +156,7 @@ func (self *SRouteTable) fetchRoutesForIP() error {
return errors.Wrap(err, "get vpc info error")
}
routeArray, err := ret.GetArray("routes")
routes := make([]cloudprovider.ICloudRoute, 0, len(routeArray))
routes := make([]*SRouteEntry, 0, len(routeArray))
for i := range routeArray {
destination, err := routeArray[i].GetString("destination")
if err != nil {
@@ -180,7 +184,7 @@ func (self *SRouteTable) fetchRoutesForPeer() error {
if err != nil {
return errors.Wrap(err, "get peer route error")
}
routesPeer := make([]cloudprovider.ICloudRoute, 0, retPeer.Total)
routesPeer := make([]*SRouteEntry, 0, retPeer.Total)
for i := range retPeer.Data {
route := retPeer.Data[i]
id, err := route.GetString("id")
@@ -254,3 +258,26 @@ func (self *SRegion) GetRouteTables(vpcId string) ([]SRouteTable, error) {
}
return ret, nil
}
func (self *SRegion) CreatePeeringRoute(vpcId, destinationCidr, target string) error {
params := jsonutils.NewDict()
routeObj := jsonutils.NewDict()
routeObj.Set("type", jsonutils.NewString("peering"))
routeObj.Set("nexthop", jsonutils.NewString(target))
routeObj.Set("destination", jsonutils.NewString(destinationCidr))
routeObj.Set("vpc_id", jsonutils.NewString(vpcId))
params.Set("route", routeObj)
err := DoCreate(self.ecsClient.VpcRoutes.Create, params, nil)
if err != nil {
return errors.Wrapf(err, "DoCreate(self.ecsClient.VpcRoutes.Create, %s, &ret)", jsonutils.Marshal(params).String())
}
return nil
}
func (self *SRegion) DeletePeeringRoute(routeId string) error {
err := DoDelete(self.ecsClient.VpcRoutes.Delete, routeId, nil, nil)
if err != nil {
return errors.Wrapf(err, "DoDelete(self.ecsClient.VpcRoutes.Delete,%s,nil)", routeId)
}
return nil
}
+65
View File
@@ -15,6 +15,7 @@
package shell
import (
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud/huawei"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
@@ -54,4 +55,68 @@ func init() {
return cli.DeleteVpc(args.ID)
})
type VpcPeeringListOPtion struct {
VPCID string
}
shellutils.R(&VpcPeeringListOPtion{}, "vpcPeering-list", "List vpcPeering", func(cli *huawei.SRegion, args *VpcPeeringListOPtion) error {
vpcPeerings, err := cli.GetVpcPeerings(args.VPCID)
if err != nil {
return err
}
printList(vpcPeerings, 0, 0, 0, nil)
return nil
})
type VpcPeeringShowOPtion struct {
VPCPEERINGID string
}
shellutils.R(&VpcPeeringShowOPtion{}, "vpcPeering-show", "show vpcPeering", func(cli *huawei.SRegion, args *VpcPeeringShowOPtion) error {
vpcPeering, err := cli.GetVpcPeering(args.VPCPEERINGID)
if err != nil {
return err
}
printObject(vpcPeering)
return nil
})
type VpcPeeringCreateOPtion struct {
NAME string
VPCID string
PEERVPCID string
PEEROWNERID string
}
shellutils.R(&VpcPeeringCreateOPtion{}, "vpcPeering-create", "create vpcPeering", func(cli *huawei.SRegion, args *VpcPeeringCreateOPtion) error {
opts := cloudprovider.VpcPeeringConnectionCreateOptions{}
opts.Name = args.NAME
opts.PeerVpcId = args.PEERVPCID
opts.PeerAccountId = args.PEEROWNERID
vpcPeering, err := cli.CreateVpcPeering(args.VPCID, &opts)
if err != nil {
return err
}
printObject(vpcPeering)
return nil
})
type VpcPeeringAcceptOPtion struct {
VPCPEERINGID string
}
shellutils.R(&VpcPeeringAcceptOPtion{}, "vpcPeering-accept", "Accept vpcPeering", func(cli *huawei.SRegion, args *VpcPeeringAcceptOPtion) error {
err := cli.AcceptVpcPeering(args.VPCPEERINGID)
if err != nil {
return err
}
return nil
})
type VpcPeeringDeleteOPtion struct {
VPCPEERINGID string
}
shellutils.R(&VpcPeeringDeleteOPtion{}, "vpcPeering-delete", "Delete vpcPeering", func(cli *huawei.SRegion, args *VpcPeeringDeleteOPtion) error {
err := cli.DeleteVpcPeering(args.VPCPEERINGID)
if err != nil {
return err
}
return nil
})
}
+73
View File
@@ -214,6 +214,79 @@ func (self *SVpc) GetINatGateways() ([]cloudprovider.ICloudNatGateway, error) {
return ret, nil
}
func (self *SVpc) GetICloudVpcPeeringConnections() ([]cloudprovider.ICloudVpcPeeringConnection, error) {
svpcPCs, err := self.getVpcPeeringConnections()
if err != nil {
return nil, errors.Wrap(err, "self.getVpcPeeringConnections()")
}
ivpcPCs := []cloudprovider.ICloudVpcPeeringConnection{}
for i := range svpcPCs {
ivpcPCs = append(ivpcPCs, &svpcPCs[i])
}
return ivpcPCs, nil
}
func (self *SVpc) GetICloudVpcPeeringConnectionById(id string) (cloudprovider.ICloudVpcPeeringConnection, error) {
svpcPC, err := self.getVpcPeeringConnectionById(id)
if err != nil {
return nil, errors.Wrapf(err, "self.getVpcPeeringConnectionById(%s)", id)
}
return svpcPC, nil
}
func (self *SVpc) CreateICloudVpcPeeringConnection(opts *cloudprovider.VpcPeeringConnectionCreateOptions) (cloudprovider.ICloudVpcPeeringConnection, error) {
svpcPC, err := self.region.CreateVpcPeering(self.GetId(), opts)
if err != nil {
return nil, errors.Wrapf(err, "self.region.CreateVpcPeering(%s,%s)", self.GetId(), jsonutils.Marshal(opts).String())
}
svpcPC.vpc = self
return svpcPC, nil
}
func (self *SVpc) AcceptICloudVpcPeeringConnection(id string) error {
vpcPC, err := self.getVpcPeeringConnectionById(id)
if err != nil {
return errors.Wrapf(err, "self.getVpcPeeringConnectionById(%s)", id)
}
if vpcPC.GetStatus() == api.VPC_PEERING_CONNECTION_STATUS_ACTIVE {
return nil
}
if vpcPC.GetStatus() == api.VPC_PEERING_CONNECTION_STATUS_UNKNOWN {
return errors.Wrapf(cloudprovider.ErrInvalidStatus, "vpcPC: %s", jsonutils.Marshal(vpcPC).String())
}
err = self.region.AcceptVpcPeering(id)
if err != nil {
return errors.Wrapf(err, "self.region.AcceptVpcPeering(%s)", id)
}
return nil
}
func (self *SVpc) GetAuthorityOwnerId() string {
return self.region.client.projectId
}
func (self *SVpc) getVpcPeeringConnections() ([]SVpcPeering, error) {
svpcPeerings, err := self.region.GetVpcPeerings(self.GetId())
if err != nil {
return nil, errors.Wrapf(err, "self.region.GetVpcPeerings(%s)", self.GetId())
}
vpcPCs := []SVpcPeering{}
for i := range svpcPeerings {
if svpcPeerings[i].GetVpcId() == self.GetId() {
svpcPeerings[i].vpc = self
vpcPCs = append(vpcPCs, svpcPeerings[i])
}
}
return vpcPCs, nil
}
func (self *SVpc) getVpcPeeringConnectionById(id string) (*SVpcPeering, error) {
svpcPC, err := self.region.GetVpcPeering(id)
if err != nil {
return nil, errors.Wrapf(err, "self.region.GetVpcPeering(%s)", id)
}
svpcPC.vpc = self
return svpcPC, nil
}
func (self *SRegion) getVpc(vpcId string) (*SVpc, error) {
vpc := SVpc{}
err := DoGet(self.ecsClient.Vpcs.Get, vpcId, nil, &vpc)
+158
View File
@@ -0,0 +1,158 @@
// 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 huawei
import (
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud"
)
type RequestVpcInfo struct {
VpcID string `json:"vpc_id"`
TenantID string `json:"tenant_id"`
}
type AcceptVpcInfo struct {
VpcID string `json:"vpc_id"`
TenantID string `json:"tenant_id"`
}
type SVpcPeering struct {
multicloud.SResourceBase
vpc *SVpc
RequestVpcInfo RequestVpcInfo `json:"request_vpc_info"`
AcceptVpcInfo AcceptVpcInfo `json:"accept_vpc_info"`
Name string `json:"name"`
ID string `json:"id"`
Status string `json:"status"`
}
func (self *SRegion) GetVpcPeerings(vpcId string) ([]SVpcPeering, error) {
querys := make(map[string]string)
querys["vpc_id"] = vpcId
vpcPeerings := make([]SVpcPeering, 0)
err := doListAllWithMarker(self.ecsClient.VpcPeerings.List, querys, &vpcPeerings)
if err != nil {
return nil, errors.Wrapf(err, "oListAllWithMarker(self.ecsClient.VpcPeerings.List, %s, &vpcPeerings)", jsonutils.Marshal(querys).String())
}
return vpcPeerings, nil
}
func (self *SRegion) GetVpcPeering(vpcPeeringId string) (*SVpcPeering, error) {
if len(vpcPeeringId) == 0 {
return nil, cloudprovider.ErrNotFound
}
vpcPeering := SVpcPeering{}
err := DoGet(self.ecsClient.VpcPeerings.Get, vpcPeeringId, nil, &vpcPeering)
if err != nil {
return nil, errors.Wrapf(err, "DoGet(self.ecsClient.VpcPeerings.Get, %s, nil, &vpcPeering)", vpcPeeringId)
}
return &vpcPeering, nil
}
func (self *SRegion) CreateVpcPeering(vpcId string, opts *cloudprovider.VpcPeeringConnectionCreateOptions) (*SVpcPeering, error) {
params := jsonutils.NewDict()
vpcPeeringObj := jsonutils.NewDict()
requestVpcObj := jsonutils.NewDict()
acceptVpcObj := jsonutils.NewDict()
vpcPeeringObj.Set("name", jsonutils.NewString(opts.Name))
requestVpcObj.Set("vpc_id", jsonutils.NewString(vpcId))
requestVpcObj.Set("tenant_id", jsonutils.NewString(self.client.projectId))
vpcPeeringObj.Set("request_vpc_info", requestVpcObj)
acceptVpcObj.Set("vpc_id", jsonutils.NewString(opts.PeerVpcId))
acceptVpcObj.Set("tenant_id", jsonutils.NewString(opts.PeerAccountId))
vpcPeeringObj.Set("accept_vpc_info", acceptVpcObj)
params.Set("peering", vpcPeeringObj)
ret := SVpcPeering{}
err := DoCreate(self.ecsClient.VpcPeerings.Create, params, &ret)
if err != nil {
return nil, errors.Wrapf(err, "DoCreate(self.ecsClient.VpcPeerings.Create, %s, &ret)", jsonutils.Marshal(params).String())
}
return &ret, nil
}
func (self *SRegion) AcceptVpcPeering(vpcPeeringId string) error {
err := DoUpdateWithSpec(self.ecsClient.VpcPeerings.UpdateInContextWithSpec, vpcPeeringId, "accept", nil)
if err != nil {
return errors.Wrapf(err, "DoUpdateWithSpec(self.ecsClient.VpcPeerings.UpdateInContextWithSpec, %s, accept, nil)", vpcPeeringId)
}
return nil
}
func (self *SRegion) DeleteVpcPeering(vpcPeeringId string) error {
err := DoDelete(self.ecsClient.VpcPeerings.Delete, vpcPeeringId, nil, nil)
if err != nil {
return errors.Wrapf(err, "DoDelete(self.ecsClient.VpcPeerings.Delete,%s,nil)", vpcPeeringId)
}
return nil
}
func (self *SVpcPeering) GetId() string {
return self.ID
}
func (self *SVpcPeering) GetName() string {
return self.Name
}
func (self *SVpcPeering) GetGlobalId() string {
return self.GetId()
}
func (self *SVpcPeering) GetStatus() string {
switch self.Status {
case "PENDING_ACCEPTANCE":
return api.VPC_PEERING_CONNECTION_STATUS_PENDING_ACCEPT
case "ACTIVE":
return api.VPC_PEERING_CONNECTION_STATUS_ACTIVE
default:
return api.VPC_PEERING_CONNECTION_STATUS_UNKNOWN
}
}
func (self *SVpcPeering) Refresh() error {
peer, err := self.vpc.region.GetVpcPeering(self.ID)
if err != nil {
return errors.Wrapf(err, "self.region.GetVpcPeering(%s)", self.ID)
}
return jsonutils.Update(self, peer)
}
func (self *SVpcPeering) GetVpcId() string {
return self.RequestVpcInfo.VpcID
}
func (self *SVpcPeering) GetPeerVpcId() string {
return self.AcceptVpcInfo.VpcID
}
func (self *SVpcPeering) GetPeerAccountId() string {
return self.AcceptVpcInfo.TenantID
}
func (self *SVpcPeering) GetEnabled() bool {
return true
}
func (self *SVpcPeering) Delete() error {
err := self.vpc.region.DeleteVpcPeering(self.ID)
if err != nil {
return errors.Wrapf(err, "self.region.DeleteVpcPeering(%s)", self.ID)
}
return nil
}
@@ -21,6 +21,7 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/utils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
@@ -61,6 +62,27 @@ func (self *SQcloudProviderFactory) IsSupportCreateCloudgroup() bool {
return true
}
func (self *SQcloudProviderFactory) IsSupportCrossCloudEnvVpcPeering() bool {
return false
}
func (self *SQcloudProviderFactory) IsSupportCrossRegionVpcPeering() bool {
return true
}
func (self *SQcloudProviderFactory) IsSupportVpcPeeringVpcCidrOverlap() bool {
return false
}
func (self *SQcloudProviderFactory) ValidateCrossRegionVpcPeeringBandWidth(bandwidth int) error {
validatedBandwidths := []int{10, 20, 50, 100, 200, 500, 1000}
ok, _ := utils.InArray(bandwidth, validatedBandwidths)
if ok {
return nil
}
return httperrors.NewInputParameterError("require validated qcloud cross region vpcPeering bandwidth values:[10, 20, 50, 100, 200, 500, 1000],unit Mbps")
}
func (self *SQcloudProviderFactory) GetSupportedDnsZoneTypes() []cloudprovider.TDnsZoneType {
return []cloudprovider.TDnsZoneType{
cloudprovider.PublicZone,
+11 -6
View File
@@ -88,6 +88,7 @@ func (cfg *QcloudClientConfig) Debug(debug bool) *QcloudClientConfig {
type SQcloudClient struct {
*QcloudClientConfig
uin string
ownerId string
ownerName string
@@ -234,11 +235,13 @@ func (r *phpJsonRequest) GetPath() string {
// 2017vpc专用response
type vpc2017JsonResponse struct {
Code int `json:"code"`
CodeDesc string `json:"codeDesc"`
Message string `json:"message"`
TotalCount int `json:"totalCount"`
Response *interface{} `json:"data"`
Code int `json:"code"`
CodeDesc string `json:"codeDesc"`
Message string `json:"message"`
TotalCount int `json:"totalCount"`
TaskId int64 `json:"taskId"`
PeeringConnectionId string `json:"peeringConnectionId"`
Response *interface{} `json:"data"`
}
func (r *vpc2017JsonResponse) ParseErrorFromHTTPResponse(body []byte) (err error) {
@@ -257,9 +260,11 @@ func (r *vpc2017JsonResponse) ParseErrorFromHTTPResponse(body []byte) (err error
func (r *vpc2017JsonResponse) GetResponse() *interface{} {
if r.Response == nil {
result, _ := jsonutils.Parse([]byte(`{"data":[],"totalCount":0}`))
resultMap := result.(*jsonutils.JSONDict)
resultMap.Update(jsonutils.Marshal(r))
return func(resp interface{}) *interface{} {
return &resp
}(result)
}(resultMap)
}
return func(resp interface{}) *interface{} {
return &resp
+116
View File
@@ -15,6 +15,7 @@
package shell
import (
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud/qcloud"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
@@ -52,4 +53,119 @@ func init() {
shellutils.R(&VpcDeleteOptions{}, "vpc-delete", "Delete vpc", func(cli *qcloud.SRegion, args *VpcDeleteOptions) error {
return cli.DeleteVpc(args.ID)
})
type VpcPCListOption struct {
VPCID string
Limit int `help:"page size"`
Offset int `help:"page offset"`
}
shellutils.R(&VpcPCListOption{}, "vpcPC-list", "List vpc peering connections", func(cli *qcloud.SRegion, args *VpcPCListOption) error {
vpcs, total, err := cli.DescribeVpcPeeringConnections(args.VPCID, "", args.Offset, args.Limit)
if err != nil {
return err
}
printList(vpcs, total, args.Offset, args.Limit, []string{})
return nil
})
type VpcPCShowOption struct {
VPCPCID string
}
shellutils.R(&VpcPCShowOption{}, "vpcPC-show", "show vpc peering connection", func(cli *qcloud.SRegion, args *VpcPCShowOption) error {
vpcPC, err := cli.GetVpcPeeringConnectionbyId(args.VPCPCID)
if err != nil {
return err
}
printObject(vpcPC)
return nil
})
type VpcPCCreateOPtion struct {
NAME string
VPCID string
PEERVPCID string
PEERREGIONID string
PEEROWNERID string
Bandwidth int
}
shellutils.R(&VpcPCCreateOPtion{}, "vpcPC-create", "create vpc peering connection", func(cli *qcloud.SRegion, args *VpcPCCreateOPtion) error {
opts := cloudprovider.VpcPeeringConnectionCreateOptions{}
opts.Name = args.NAME
opts.PeerVpcId = args.PEERVPCID
opts.PeerAccountId = args.PEEROWNERID
opts.PeerRegionId = args.PEERREGIONID
vpcPCId, err := cli.CreateVpcPeeringConnection(args.VPCID, &opts)
if err != nil {
return err
}
printObject(vpcPCId)
return nil
})
shellutils.R(&VpcPCCreateOPtion{}, "vpcPC-createEx", "create Ex vpc peering connection", func(cli *qcloud.SRegion, args *VpcPCCreateOPtion) error {
opts := cloudprovider.VpcPeeringConnectionCreateOptions{}
opts.Name = args.NAME
opts.PeerVpcId = args.PEERVPCID
opts.PeerAccountId = args.PEEROWNERID
opts.PeerRegionId = args.PEERREGIONID
opts.Bandwidth = args.Bandwidth
taskId, err := cli.CreateVpcPeeringConnectionEx(args.VPCID, &opts)
if err != nil {
return err
}
printObject(taskId)
return nil
})
type VpcPeeringAcceptOPtion struct {
VPCPEERINGID string
}
shellutils.R(&VpcPeeringAcceptOPtion{}, "vpcPC-accept", "Accept vpcPeering", func(cli *qcloud.SRegion, args *VpcPeeringAcceptOPtion) error {
err := cli.AcceptVpcPeeringConnection(args.VPCPEERINGID)
if err != nil {
return err
}
return nil
})
shellutils.R(&VpcPeeringAcceptOPtion{}, "vpcPC-acceptEx", "Accept Ex vpcPeering", func(cli *qcloud.SRegion, args *VpcPeeringAcceptOPtion) error {
_, err := cli.AcceptVpcPeeringConnectionEx(args.VPCPEERINGID)
if err != nil {
return err
}
return nil
})
type VpcPeeringDeleteOPtion struct {
VPCPEERINGID string
}
shellutils.R(&VpcPeeringAcceptOPtion{}, "vpcPC-delete", "Delete vpcPeering", func(cli *qcloud.SRegion, args *VpcPeeringAcceptOPtion) error {
err := cli.DeleteVpcPeeringConnection(args.VPCPEERINGID)
if err != nil {
return err
}
return nil
})
shellutils.R(&VpcPeeringAcceptOPtion{}, "vpcPC-deleteEx", "Delete Ex vpcPeering", func(cli *qcloud.SRegion, args *VpcPeeringAcceptOPtion) error {
status, err := cli.DeleteVpcPeeringConnectionEx(args.VPCPEERINGID)
if err != nil {
return err
}
println(status)
return nil
})
type VpcTaskShowOption struct {
TASKID string
}
shellutils.R(&VpcTaskShowOption{}, "vpcTask-show", "show vpc task", func(cli *qcloud.SRegion, args *VpcTaskShowOption) error {
status, err := cli.DescribeVpcTaskResult(args.TASKID)
if err != nil {
return err
}
println(status)
return nil
})
}
+156
View File
@@ -15,9 +15,11 @@
package qcloud
import (
"fmt"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
@@ -200,3 +202,157 @@ func (self *SVpc) addWire(wire *SWire) {
}
self.iwires = append(self.iwires, wire)
}
func (self *SVpc) GetSVpcPeeringConnections() ([]SVpcPC, error) {
svpcPCs, err := self.region.GetAllVpcPeeringConnections(self.GetId())
if err != nil {
return nil, errors.Wrapf(err, "self.region.GetAllVpcPeeringConnections(%s)", self.GetId())
}
for i := range svpcPCs {
svpcPCs[i].vpc = self
}
return svpcPCs, nil
}
func (self *SVpc) GetSVpcPeeringConnectionById(id string) (*SVpcPC, error) {
svpcPC, err := self.region.GetVpcPeeringConnectionbyId(id)
if err != nil {
return nil, errors.Wrapf(err, "self.region.GetVpcPeeringConnectionbyId(%s)", id)
}
svpcPC.vpc = self
return svpcPC, nil
}
func (self *SVpc) CreateSVpcPeeringConnection(opts *cloudprovider.VpcPeeringConnectionCreateOptions) (*SVpcPC, error) {
vpcPCId, err := self.region.CreateVpcPeeringConnection(self.GetId(), opts)
if err != nil {
return nil, errors.Wrapf(err, "self.region.CreateVpcPeeringConnection(%s, %s)", self.GetId(), jsonutils.Marshal(opts).String())
}
SvpcPC, err := self.GetSVpcPeeringConnectionById(vpcPCId)
if err != nil {
return nil, errors.Wrapf(err, "self.GetSVpcPeeringConnectionById(%s)", vpcPCId)
}
return SvpcPC, nil
}
func (self *SVpc) CreateCrossRegionSVpcPeeringConnection(opts *cloudprovider.VpcPeeringConnectionCreateOptions) (*SVpcPC, error) {
taskId, err := self.region.CreateVpcPeeringConnectionEx(self.GetId(), opts)
if err != nil {
return nil, errors.Wrapf(err, "self.region.CreateVpcPeeringConnectionEx(%s, %s)", self.GetId(), jsonutils.Marshal(opts).String())
}
err = cloudprovider.Wait(time.Second*5, time.Minute*6, func() (bool, error) {
status, err := self.region.DescribeVpcTaskResult(fmt.Sprintf("%d", taskId))
if err != nil {
return false, errors.Wrap(err, "self.vpc.region.DescribeVpcTaskResult")
}
//任务的当前状态。0:成功,1:失败,2:进行中。
if status == 1 {
return false, errors.Wrap(fmt.Errorf("taskfailed,taskId=%s", taskId), "client.DescribeVpcTaskResult(taskId)")
}
if status == 0 {
return true, nil
}
return false, nil
})
if err != nil {
return nil, errors.Wrapf(err, " cloudprovider.Wait %s", taskId)
}
svpcPCs, err := self.GetSVpcPeeringConnections()
if err != nil {
return nil, errors.Wrap(err, "self.GetSVpcPeeringConnections()")
}
for i := range svpcPCs {
if svpcPCs[i].GetPeerVpcId() == opts.PeerVpcId {
return &svpcPCs[i], nil
}
}
return nil, errors.Wrap(cloudprovider.ErrNotFound, "vpcPeeringConnection not found after createEx")
}
func (self *SVpc) AcceptSVpcPeeringConnection(id string) error {
err := self.region.AcceptVpcPeeringConnection(id)
if err != nil {
return errors.Wrapf(err, "self.region.AcceptVpcPeeringConnection(%s)", id)
}
return nil
}
func (self *SVpc) AcceptCrossRegionSVpcPeeringConnection(id string) error {
taskId, err := self.region.AcceptVpcPeeringConnectionEx(id)
if err != nil {
return errors.Wrapf(err, "self.region.AcceptVpcPeeringConnectionEx(%s)", id)
}
err = cloudprovider.Wait(time.Second*5, time.Minute*6, func() (bool, error) {
status, err := self.region.DescribeVpcTaskResult(fmt.Sprintf("%d", taskId))
if err != nil {
return false, errors.Wrap(err, "self.vpc.region.DescribeVpcTaskResult")
}
//任务的当前状态。0:成功,1:失败,2:进行中。
if status == 1 {
return false, errors.Wrap(fmt.Errorf("taskfailed,taskId=%s", taskId), "client.DescribeVpcTaskResult(taskId)")
}
if status == 0 {
return true, nil
}
return false, nil
})
if err != nil {
return errors.Wrapf(err, " cloudprovider.Wait %s", taskId)
}
svpcPC, err := self.GetSVpcPeeringConnectionById(id)
if err != nil {
return errors.Wrapf(err, "self.GetSVpcPeeringConnectionById(%s)", id)
}
if svpcPC.GetStatus() != api.VPC_PEERING_CONNECTION_STATUS_ACTIVE {
return errors.Wrap(cloudprovider.ErrInvalidStatus, "invalid status after AcceptCrossRegionSVpcPeeringConnection")
}
return nil
}
func (self *SVpc) GetICloudVpcPeeringConnections() ([]cloudprovider.ICloudVpcPeeringConnection, error) {
result := []cloudprovider.ICloudVpcPeeringConnection{}
SVpcPCs, err := self.GetSVpcPeeringConnections()
if err != nil {
return nil, errors.Wrap(err, "self.GetSVpcPeeringConnections()")
}
for i := range SVpcPCs {
result = append(result, &SVpcPCs[i])
}
return result, nil
}
func (self *SVpc) GetICloudVpcPeeringConnectionById(id string) (cloudprovider.ICloudVpcPeeringConnection, error) {
svpcPC, err := self.GetSVpcPeeringConnectionById(id)
if err != nil {
return nil, errors.Wrapf(err, "self.GetSVpcPeeringConnectionById(%s)", id)
}
return svpcPC, nil
}
func (self *SVpc) CreateICloudVpcPeeringConnection(opts *cloudprovider.VpcPeeringConnectionCreateOptions) (cloudprovider.ICloudVpcPeeringConnection, error) {
if self.GetRegion().GetId() == opts.PeerRegionId {
return self.CreateSVpcPeeringConnection(opts)
} else {
return self.CreateCrossRegionSVpcPeeringConnection(opts)
}
}
func (self *SVpc) AcceptICloudVpcPeeringConnection(id string) error {
svpcPC, err := self.GetSVpcPeeringConnectionById(id)
if err != nil {
return errors.Wrapf(err, "self.GetSVpcPeeringConnectionById(%s)", id)
}
if svpcPC.GetStatus() == api.VPC_PEERING_CONNECTION_STATUS_ACTIVE {
return nil
}
if !svpcPC.IsCrossRegion() {
return self.AcceptSVpcPeeringConnection(id)
} else {
return self.AcceptCrossRegionSVpcPeeringConnection(id)
}
}
func (self *SVpc) GetAuthorityOwnerId() string {
return self.region.client.ownerName
}
@@ -0,0 +1,282 @@
// 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 qcloud
import (
"fmt"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud"
)
type SVpcPC struct {
multicloud.SResourceBase
vpc *SVpc
VpcID string `json:"vpcId"`
UnVpcID string `json:"unVpcId"`
PeerVpcID string `json:"peerVpcId"`
UnPeerVpcID string `json:"unPeerVpcId"`
AppID string `json:"appId"`
PeeringConnectionID string `json:"peeringConnectionId"`
PeeringConnectionName string `json:"peeringConnectionName"`
State int `json:"state"`
CreateTime string `json:"createTime"`
Uin string `json:"uin"`
PeerUin string `json:"peerUin"`
Region string `json:"region"`
PeerRegion string `json:"peerRegion"`
}
func (region *SRegion) DescribeVpcPeeringConnections(vpcId string, peeringConnectionId string, offset int, limit int) ([]SVpcPC, int, error) {
if limit > 50 || limit <= 0 {
limit = 50
}
params := make(map[string]string)
params["offset"] = fmt.Sprintf("%d", offset)
params["limit"] = fmt.Sprintf("%d", limit)
if len(vpcId) > 0 {
params["vpcId"] = vpcId
}
if len(peeringConnectionId) > 0 {
params["peeringConnectionId"] = peeringConnectionId
}
body, err := region.vpc2017Request("DescribeVpcPeeringConnections", params)
if err != nil {
return nil, 0, errors.Wrapf(err, `region.vpcRequest("DescribeVpcPeeringConnections", params)`, jsonutils.Marshal(params).String())
}
total, _ := body.Float("totalCount")
if total <= 0 {
return nil, int(total), nil
}
vpcPCs := make([]SVpcPC, 0)
err = body.Unmarshal(&vpcPCs, "data")
if err != nil {
return nil, 0, errors.Wrapf(err, "body.Unmarshal(&vpcPCs,%s)", body.String())
}
return vpcPCs, int(total), nil
}
func (region *SRegion) GetAllVpcPeeringConnections(vpcId string) ([]SVpcPC, error) {
result := []SVpcPC{}
for {
vpcPCS, total, err := region.DescribeVpcPeeringConnections(vpcId, "", len(result), 50)
if err != nil {
return nil, errors.Wrapf(err, `client.DescribeVpcPeeringConnections(%s,"",%d,50)`, vpcId, len(result), len(result))
}
result = append(result, vpcPCS...)
if total <= len(result) {
break
}
}
return result, nil
}
func (region *SRegion) GetVpcPeeringConnectionbyId(vpcPCId string) (*SVpcPC, error) {
vpcPCs, _, err := region.DescribeVpcPeeringConnections("", vpcPCId, 0, 50)
if err != nil {
return nil, errors.Wrapf(err, `client.DescribeVpcPeeringConnections("", %s, 0, 50)`, vpcPCId)
}
if len(vpcPCs) < 1 {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "GetVpcPeeringConnectionbyId(%s)", vpcPCId)
}
if len(vpcPCs) > 1 {
return nil, errors.Wrapf(cloudprovider.ErrDuplicateId, "GetVpcPeeringConnectionbyId(%s)", vpcPCId)
}
return &vpcPCs[0], nil
}
func (region *SRegion) CreateVpcPeeringConnection(vpcId string, opts *cloudprovider.VpcPeeringConnectionCreateOptions) (string, error) {
params := make(map[string]string)
params["vpcId"] = vpcId
params["peerVpcId"] = opts.PeerVpcId
params["peerUin"] = opts.PeerAccountId
params["peeringConnectionName"] = opts.Name
body, err := region.vpc2017Request("CreateVpcPeeringConnection", params)
if err != nil {
return "", errors.Wrapf(err, `client.vpc2017Request("CreateVpcPeeringConnection", %s)`, jsonutils.Marshal(params).String())
}
peeringId, err := body.GetString("peeringConnectionId")
if err != nil {
return "", errors.Wrapf(err, `%s body.GetString("peeringConnectionId")`, body.String())
}
return peeringId, nil
}
func (region *SRegion) AcceptVpcPeeringConnection(peeringId string) error {
params := make(map[string]string)
params["peeringConnectionId"] = peeringId
_, err := region.vpc2017Request("AcceptVpcPeeringConnection", params)
if err != nil {
return errors.Wrapf(err, `client.vpc2017Request("AcceptVpcPeeringConnection",%s)`, jsonutils.Marshal(params).String())
}
return nil
}
func (region *SRegion) DeleteVpcPeeringConnection(peeringId string) error {
params := make(map[string]string)
params["peeringConnectionId"] = peeringId
_, err := region.vpc2017Request("DeleteVpcPeeringConnection", params)
if err != nil {
return errors.Wrapf(err, `client.vpc2017Request("DeleteVpcPeeringConnection",%s)`, jsonutils.Marshal(params).String())
}
return nil
}
func (region *SRegion) CreateVpcPeeringConnectionEx(vpcId string, opts *cloudprovider.VpcPeeringConnectionCreateOptions) (int64, error) {
params := make(map[string]string)
params["vpcId"] = vpcId
params["peerVpcId"] = opts.PeerVpcId
params["peerUin"] = opts.PeerAccountId
params["peeringConnectionName"] = opts.Name
params["peerRegion"] = opts.PeerRegionId
params["bandwidth"] = fmt.Sprintf("%d", opts.Bandwidth)
body, err := region.vpc2017Request("CreateVpcPeeringConnectionEx", params)
if err != nil {
return 0, errors.Wrapf(err, `client.vpc2017Request("CreateVpcPeeringConnectionEx", %s)`, jsonutils.Marshal(params).String())
}
taskId, err := body.Int("taskId")
if err != nil {
return 0, errors.Wrapf(err, `%s body.Int("taskId")`, body.String())
}
return taskId, nil
}
func (region *SRegion) DescribeVpcTaskResult(taskId string) (int, error) {
params := make(map[string]string)
params["taskId"] = taskId
body, err := region.vpc2017Request("DescribeVpcTaskResult", params)
if err != nil {
return 0, errors.Wrapf(err, `client.vpc2017Request("DescribeVpcTaskResult",%s)`, taskId)
}
status, err := body.Float("data", "status")
if err != nil {
return 0, errors.Wrapf(err, `%s body.Int("data.status")`, body.String())
}
return int(status), nil
}
func (region *SRegion) AcceptVpcPeeringConnectionEx(peeringId string) (int64, error) {
params := make(map[string]string)
params["peeringConnectionId"] = peeringId
body, err := region.vpc2017Request("AcceptVpcPeeringConnectionEx", params)
if err != nil {
return 0, errors.Wrapf(err, `client.vpc2017Request("AcceptVpcPeeringConnectionEx", %s)`, jsonutils.Marshal(params).String())
}
taskId, err := body.Int("taskId")
if err != nil {
return 0, errors.Wrapf(err, `%s body.Int("taskId")`, body.String())
}
return taskId, nil
}
func (region *SRegion) DeleteVpcPeeringConnectionEx(peeringId string) (int64, error) {
params := make(map[string]string)
params["peeringConnectionId"] = peeringId
body, err := region.vpc2017Request("DeleteVpcPeeringConnectionEx", params)
if err != nil {
return 0, errors.Wrapf(err, `client.vpc2017Request("DeleteVpcPeeringConnectionEx",%s)`, jsonutils.Marshal(params).String())
}
taskId, err := body.Int("taskId")
if err != nil {
return 0, errors.Wrapf(err, `%s body.Int("taskId")`, body.String())
}
return taskId, nil
}
func (self *SVpcPC) GetId() string {
return self.PeeringConnectionID
}
func (self *SVpcPC) GetName() string {
return self.PeeringConnectionName
}
func (self *SVpcPC) GetGlobalId() string {
return self.GetId()
}
func (self *SVpcPC) GetStatus() string {
switch self.State {
case 1:
return api.VPC_PEERING_CONNECTION_STATUS_ACTIVE
case 0:
return api.VPC_PEERING_CONNECTION_STATUS_PENDING_ACCEPT
default:
return api.VPC_PEERING_CONNECTION_STATUS_UNKNOWN
}
}
func (self *SVpcPC) Refresh() error {
svpcPC, err := self.vpc.region.GetVpcPeeringConnectionbyId(self.GetId())
if err != nil {
return errors.Wrapf(err, "self.vpc.region.GetVpcPeeringConnectionbyId(%s)", self.GetId())
}
return jsonutils.Update(self, svpcPC)
}
func (self *SVpcPC) GetPeerVpcId() string {
return self.UnPeerVpcID
}
func (self *SVpcPC) GetPeerAccountId() string {
return self.PeerUin
}
func (self *SVpcPC) GetEnabled() bool {
return true
}
func (self *SVpcPC) Delete() error {
if !self.IsCrossRegion() {
return self.vpc.region.DeleteVpcPeeringConnection(self.GetId())
}
taskId, err := self.vpc.region.DeleteVpcPeeringConnectionEx(self.GetId())
if err != nil {
return errors.Wrapf(err, "self.vpc.region.DeleteVpcPeeringConnection(%s)", self.GetId())
}
//err = self.vpc.region.WaitVpcTask(fmt.Sprintf("%d", taskId), time.Second*5, time.Minute*10)
err = cloudprovider.Wait(time.Second*5, time.Minute*6, func() (bool, error) {
status, err := self.vpc.region.DescribeVpcTaskResult(fmt.Sprintf("%d", taskId))
if err != nil {
return false, errors.Wrap(err, "self.vpc.region.DescribeVpcTaskResult")
}
//任务的当前状态。0:成功,1:失败,2:进行中。
if status == 1 {
return false, errors.Wrap(fmt.Errorf("taskfailed,taskId=%s", taskId), "client.DescribeVpcTaskResult(taskId)")
}
if status == 0 {
return true, nil
}
return false, nil
})
if err != nil {
return errors.Wrapf(err, "self.region.WaitTask(%s)", taskId)
}
return nil
}
func (self *SVpcPC) IsCrossRegion() bool {
if len(self.Region) == 0 {
return false
}
return self.Region != self.PeerRegion
}
+32 -31
View File
@@ -15,130 +15,131 @@
package multicloud
import (
"fmt"
"time"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
type SRegion struct{}
func (r *SRegion) GetIDiskById(id string) (cloudprovider.ICloudDisk, error) {
return nil, fmt.Errorf("Not Implement GetIDiskById")
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetIDiskById")
}
func (r *SRegion) GetIHostById(id string) (cloudprovider.ICloudHost, error) {
return nil, fmt.Errorf("Not Implement GetIHostById")
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetIHostById")
}
func (r *SRegion) GetIHosts() ([]cloudprovider.ICloudHost, error) {
return nil, fmt.Errorf("Not Implement GetIHosts")
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetIHosts")
}
func (r *SRegion) GetISnapshotById(snapshotId string) (cloudprovider.ICloudSnapshot, error) {
return nil, fmt.Errorf("Not Implement GetISnapshotById")
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetISnapshotById")
}
func (r *SRegion) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) {
return nil, fmt.Errorf("Not Implement GetISnapshots")
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetISnapshots")
}
func (r *SRegion) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) {
return nil, fmt.Errorf("Not Implement GetIStorageById")
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetIStorageById")
}
func (r *SRegion) GetIStoragecacheById(id string) (cloudprovider.ICloudStoragecache, error) {
return nil, fmt.Errorf("Not Implement GetIStoragecacheById")
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetIStoragecacheById")
}
func (r *SRegion) GetIStoragecaches() ([]cloudprovider.ICloudStoragecache, error) {
return nil, fmt.Errorf("Not Implement GetIStoragecaches")
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetIStoragecaches")
}
func (r *SRegion) GetIStorages() ([]cloudprovider.ICloudStorage, error) {
return nil, fmt.Errorf("Not Implement GetIStorages")
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetIStorages")
}
func (r *SRegion) GetIVMById(id string) (cloudprovider.ICloudVM, error) {
return nil, fmt.Errorf("Not Implement GetIVMById")
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetIVMById")
}
func (r *SRegion) CreateSnapshotPolicy(input *cloudprovider.SnapshotPolicyInput) (string, error) {
return "", fmt.Errorf("CreateSnapshotPolicy not implement")
return "", errors.Wrapf(cloudprovider.ErrNotImplemented, "CreateSnapshotPolicy")
}
func (r *SRegion) UpdateSnapshotPolicy(input *cloudprovider.SnapshotPolicyInput, snapshotPolicyId string) error {
return fmt.Errorf("UpdateSnapshotPolicy not implement")
return errors.Wrapf(cloudprovider.ErrNotImplemented, "UpdateSnapshotPolicy")
}
func (r *SRegion) GetISnapshotPolicyById(snapshotPolicyId string) (cloudprovider.ICloudSnapshotPolicy, error) {
return nil, fmt.Errorf("GetISnapshotPolicyById not implement")
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetISnapshotPolicyById")
}
func (self *SRegion) GetISnapshotPolicies() ([]cloudprovider.ICloudSnapshotPolicy, error) {
return nil, fmt.Errorf("GetISnapshotPolicies not implement")
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetISnapshotPolicies")
}
func (self *SRegion) DeleteSnapshotPolicy(string) error {
return fmt.Errorf("DeleteSnapshotPolicy not implement")
return errors.Wrapf(cloudprovider.ErrNotImplemented, "DeleteSnapshotPolicy")
}
func (self *SRegion) ApplySnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error {
return fmt.Errorf("ApplySnapshotPolicyToDisks not implement")
return errors.Wrapf(cloudprovider.ErrNotImplemented, "ApplySnapshotPolicyToDisks")
}
func (self *SRegion) CancelSnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error {
return fmt.Errorf("ApplySnapshotPolicyToDisks not implement")
return errors.Wrapf(cloudprovider.ErrNotImplemented, "CancelSnapshotPolicyToDisks")
}
func (self *SRegion) GetISkus() ([]cloudprovider.ICloudSku, error) {
return nil, cloudprovider.ErrNotSupported
return nil, errors.Wrapf(cloudprovider.ErrNotSupported, "GetISkus")
}
func (self *SRegion) CreateISku(name string, vCpu int, memoryMb int) error {
return fmt.Errorf("Not Implement CreateISku")
return errors.Wrapf(cloudprovider.ErrNotImplemented, "CreateISku")
}
func (self *SRegion) GetINetworkInterfaces() ([]cloudprovider.ICloudNetworkInterface, error) {
return nil, fmt.Errorf("Not Implement GetINetworkInterfaces")
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetINetworkInterfaces")
}
func (self *SRegion) GetIDBInstances() ([]cloudprovider.ICloudDBInstance, error) {
return nil, fmt.Errorf("GetIDBInstances not implement")
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetIDBInstances")
}
func (self *SRegion) GetIDBInstanceById(instanceId string) (cloudprovider.ICloudDBInstance, error) {
return nil, fmt.Errorf("GetIDBInstanceById not implement")
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetIDBInstanceById")
}
func (self *SRegion) GetIDBInstanceBackups() ([]cloudprovider.ICloudDBInstanceBackup, error) {
return nil, fmt.Errorf("Not Implemented GetIDBInstanceBackups")
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetIDBInstanceBackups")
}
func (self *SRegion) GetIDBInstanceBackupById(backupId string) (cloudprovider.ICloudDBInstanceBackup, error) {
return nil, fmt.Errorf("Not Implemented GetIDBInstanceBackupById")
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetIDBInstanceBackupById")
}
func (self *SRegion) GetIElasticcaches() ([]cloudprovider.ICloudElasticcache, error) {
return nil, fmt.Errorf("Not Implemented GetIElasticcaches")
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetIElasticcaches")
}
func (self *SRegion) CreateIDBInstance(desc *cloudprovider.SManagedDBInstanceCreateConfig) (cloudprovider.ICloudDBInstance, error) {
return nil, fmt.Errorf("Not Implemented CreateIDBInstance")
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "CreateIDBInstance")
}
func (self *SRegion) CreateIElasticcaches(ec *cloudprovider.SCloudElasticCacheInput) (cloudprovider.ICloudElasticcache, error) {
return nil, fmt.Errorf("Not Implemented CreateIElasticcaches")
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "CreateIElasticcaches")
}
func (self *SRegion) GetIElasticcacheById(id string) (cloudprovider.ICloudElasticcache, error) {
return nil, fmt.Errorf("Not Implemented GetIElasticcacheById")
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetIElasticcacheById")
}
func (self *SRegion) GetICloudEvents(start time.Time, end time.Time, withReadEvent bool) ([]cloudprovider.ICloudEvent, error) {
return nil, fmt.Errorf("Not Implemented GetICloudEvnets")
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetICloudEvents")
}
func (self *SRegion) GetICloudQuotas() ([]cloudprovider.ICloudQuota, error) {
return nil, fmt.Errorf("Not Implemented GetICloudQuotas")
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetICloudQuotas")
}
+30 -2
View File
@@ -15,7 +15,7 @@
package multicloud
import (
"fmt"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
@@ -25,5 +25,33 @@ type SVpc struct {
}
func (self *SVpc) GetINatGateways() ([]cloudprovider.ICloudNatGateway, error) {
return nil, fmt.Errorf("Not Implemented GetNatGateways")
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetINatGateways")
}
func (self *SVpc) GetICloudVpcPeeringConnections() ([]cloudprovider.ICloudVpcPeeringConnection, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetICloudVpcPeeringConnections")
}
func (self *SVpc) GetICloudVpcPeeringConnectionById(id string) (cloudprovider.ICloudVpcPeeringConnection, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetICloudVpcPeeringConnectionById")
}
func (self *SVpc) CreateICloudVpcPeeringConnection(opts *cloudprovider.VpcPeeringConnectionCreateOptions) (cloudprovider.ICloudVpcPeeringConnection, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "CreateICloudVpcPeeringConnection")
}
func (self *SVpc) AcceptICloudVpcPeeringConnection(id string) error {
return errors.Wrapf(cloudprovider.ErrNotImplemented, "AcceptICloudVpcPeeringConnection", id)
}
func (self *SVpc) GetAuthorityOwnerId() string {
return ""
}
func (self *SVpc) CreateRouteToVpcPeeringConnection(cidrBlock, peerId string) error {
return errors.Wrapf(cloudprovider.ErrNotImplemented, "CreateRouteToVpcPeeringConnection")
}
func (self *SVpc) DeleteVpcPeeringConnectionRoute(vpcPeeringConnectionId string) error {
return errors.Wrapf(cloudprovider.ErrNotImplemented, "DeleteVpcPeeringConnectionRoute")
}