aws sync routetable

This commit is contained in:
TangBin
2020-01-14 15:25:54 +08:00
parent f51ca4201d
commit aa55b51106
8 changed files with 327 additions and 3 deletions
+23
View File
@@ -0,0 +1,23 @@
package compute
const (
ROUTE_TABLE_TYPE_VPC = "VPC" // VPC路由器
ROUTE_TABLE_TYPE_VBR = "VBR" // 边界路由器
)
const (
ROUTE_ENTRY_TYPE_CUSTOM = "Custom" // 自定义路由
ROUTE_ENTRY_TYPE_SYSTEM = "System" // 系统路由
)
const (
Next_HOP_TYPE_INSTANCE = "Instance" // ECS实例。
Next_HOP_TYPE_HAVIP = "HaVip" // 高可用虚拟IP。
Next_HOP_TYPE_VPN = "VpnGateway" // VPN网关。
Next_HOP_TYPE_NAT = "NatGateway" // NAT网关。
Next_HOP_TYPE_NETWORK = "NetworkInterface" // 辅助弹性网卡。
Next_HOP_TYPE_ROUTER = "RouterInterface" // 路由器接口。
Next_HOP_TYPE_IPV6 = "IPv6Gateway" // IPv6网关。
Next_HOP_TYPE_INTERNET = "InternetGateway" // Internet网关。
Next_HOP_TYPE_EGRESS_INTERNET = "EgressInternetGateway" // egress only Internet网关。
)
+15
View File
@@ -30,6 +30,7 @@ import (
"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/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/billing"
"yunion.io/x/onecloud/pkg/util/rbacutils"
@@ -147,6 +148,20 @@ func (self *SAwsGuestDriver) GetDeployStatus() ([]string, error) {
}
func (self *SAwsGuestDriver) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, input *api.ServerCreateInput) (*api.ServerCreateInput, error) {
if len(input.Eip) > 0 || input.EipBw > 0 {
if len(input.Networks) > 0 {
inetwork, err := db.FetchByIdOrName(models.NetworkManager, userCred, input.Networks[0].Network)
if err != nil {
return nil, err
}
support_eip := inetwork.(*models.SNetwork).GetMetadataJson("support_eip", nil)
if ok, _ := support_eip.Bool(); !ok {
return nil, httperrors.NewInputParameterError("network %s associated route table has no internet gateway attached.", inetwork.GetName())
}
}
}
return self.SManagedVirtualizedGuestDriver.ValidateCreateData(ctx, userCred, input)
}
+2
View File
@@ -42,6 +42,7 @@ type SRouteEntry struct {
NextHops SNextHops
}
// Custom:自定义路由。 System:系统路由。
func (route *SRouteEntry) GetType() string {
return route.Type
}
@@ -118,6 +119,7 @@ func (self *SRouteTable) GetRegionId() string {
return self.region.RegionId
}
// VRouterVPC路由器。 VBR:边界路由器。
func (self *SRouteTable) GetType() string {
return self.RouteTableType
}
+18 -1
View File
@@ -83,7 +83,24 @@ func (self *SNetwork) IsEmulated() bool {
}
func (self *SNetwork) GetMetadata() *jsonutils.JSONDict {
return nil
meta := jsonutils.NewDict()
routes, _ := self.wire.vpc.region.GetRouteTablesByNetworkId(self.GetId())
if len(routes) == 0 {
routes, _ = self.wire.vpc.region.GetRouteTables(self.VpcId, true)
}
support_eip := false
if len(routes) >= 1 {
for i := range routes[0].Routes {
route := routes[0].Routes[i]
if route.GetNextHopType() == api.Next_HOP_TYPE_INTERNET {
support_eip = true
}
}
}
meta.Set("support_eip", jsonutils.NewBool(support_eip))
return meta
}
func (self *SNetwork) GetIWire() cloudprovider.ICloudWire {
+63
View File
@@ -0,0 +1,63 @@
package aws
import (
"strings"
api "yunion.io/x/onecloud/pkg/apis/compute"
)
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"`
}
func (self *SRoute) GetType() string {
if self.GetNextHop() == "local" {
return api.ROUTE_ENTRY_TYPE_SYSTEM
}
return api.ROUTE_ENTRY_TYPE_CUSTOM
}
func (self *SRoute) GetCidr() string {
return self.DestinationCIDRBlock
}
func (self *SRoute) GetNextHopType() string {
segs := strings.Split(self.GetNextHop(), "-")
if len(segs) == 0 {
return ""
}
switch segs[0] {
case "i":
return api.Next_HOP_TYPE_INSTANCE
case "vgw":
return api.Next_HOP_TYPE_VPN
case "pcx":
return api.Next_HOP_TYPE_ROUTER
case "eni":
return api.Next_HOP_TYPE_NETWORK
case "nat":
return api.Next_HOP_TYPE_NAT
case "igw":
return api.Next_HOP_TYPE_INTERNET
case "eigw":
return api.Next_HOP_TYPE_EGRESS_INTERNET
default:
return ""
}
}
func (self *SRoute) GetNextHop() string {
if self.GatewayID == nil {
return ""
}
return *self.GatewayID
}
+171
View File
@@ -0,0 +1,171 @@
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"
)
type SRouteTable struct {
region *SRegion
vpc *SVpc
Associations []Association `json:"Associations"`
PropagatingVgws []string `json:"PropagatingVgws"`
RouteTableID string `json:"RouteTableId"`
Routes []SRoute `json:"Routes"`
VpcID string `json:"VpcId"`
OwnerID string `json:"OwnerId"`
}
type Association struct {
Main bool `json:"Main"`
RouteTableAssociationID string `json:"RouteTableAssociationId"`
RouteTableID string `json:"RouteTableId"`
SubnetID *string `json:"SubnetId,omitempty"`
}
func (self *SRouteTable) GetId() string {
return self.RouteTableID
}
func (self *SRouteTable) GetName() string {
return ""
}
func (self *SRouteTable) GetGlobalId() string {
return self.GetId()
}
func (self *SRouteTable) GetStatus() string {
return ""
}
func (self *SRouteTable) Refresh() error {
ret, err := self.region.GetRouteTable(self.GetId())
if err != nil {
return errors.Wrap(err, "SRouteTable.Refresh.GetRouteTable")
}
err = jsonutils.Update(self, ret)
if err != nil {
return errors.Wrap(err, "SRouteTable.Refresh.Update")
}
return nil
}
func (self *SRouteTable) IsEmulated() bool {
return false
}
func (self *SRouteTable) GetMetadata() *jsonutils.JSONDict {
return nil
}
func (self *SRouteTable) GetDescription() string {
return ""
}
func (self *SRouteTable) GetRegionId() string {
return self.region.GetId()
}
func (self *SRouteTable) GetVpcId() string {
return self.VpcID
}
func (self *SRouteTable) GetType() string {
return api.ROUTE_TABLE_TYPE_VPC
}
func (self *SRouteTable) GetIRoutes() ([]cloudprovider.ICloudRoute, error) {
iroutes := make([]cloudprovider.ICloudRoute, len(self.Routes))
for i := range self.Routes {
self.Routes[i].routetable = self
iroutes[i] = &self.Routes[i]
}
return iroutes, nil
}
func (self *SRegion) GetRouteTables(vpcId string, mainRouteOnly bool) ([]SRouteTable, error) {
input := &ec2.DescribeRouteTablesInput{}
filters := make([]*ec2.Filter, 0)
filters = AppendSingleValueFilter(filters, "vpc-id", vpcId)
if mainRouteOnly {
filters = AppendSingleValueFilter(filters, "association.main", "true")
}
input.SetFilters(filters)
ret, err := self.ec2Client.DescribeRouteTables(input)
if err != nil {
return nil, errors.Wrap(err, "SRegion.GetRouteTables.DescribeRouteTables")
}
routeTables := make([]SRouteTable, len(ret.RouteTables))
err = unmarshalAwsOutput(ret, "RouteTables", routeTables)
if err != nil {
return nil, errors.Wrap(err, "SRegion.GetRouteTables.unmarshalAwsOutput")
}
for i := range routeTables {
routeTables[i].region = self
}
return routeTables, nil
}
func (self *SRegion) GetRouteTablesByNetworkId(netId string) ([]SRouteTable, error) {
input := &ec2.DescribeRouteTablesInput{}
filter := &ec2.Filter{}
filter.SetName("association.subnet-id")
filter.SetValues([]*string{&netId})
input.SetFilters([]*ec2.Filter{filter})
ret, err := self.ec2Client.DescribeRouteTables(input)
if err != nil {
return nil, errors.Wrap(err, "SRegion.GetRouteTables.DescribeRouteTables")
}
routeTables := make([]SRouteTable, len(ret.RouteTables))
err = unmarshalAwsOutput(ret, "RouteTables", routeTables)
if err != nil {
return nil, errors.Wrap(err, "SRegion.GetRouteTables.unmarshalAwsOutput")
}
for i := range routeTables {
routeTables[i].region = self
}
return routeTables, nil
}
func (self *SRegion) GetRouteTable(id string) (*SRouteTable, error) {
input := &ec2.DescribeRouteTablesInput{}
input.RouteTableIds = []*string{&id}
ret, err := self.ec2Client.DescribeRouteTables(input)
if err != nil {
return nil, errors.Wrap(err, "SRegion.GetRouteTables.DescribeRouteTables")
}
routeTables := make([]SRouteTable, len(ret.RouteTables))
err = unmarshalAwsOutput(ret, "RouteTables", routeTables)
if err != nil {
return nil, errors.Wrap(err, "SRegion.GetRouteTables.unmarshalAwsOutput")
}
if len(routeTables) == 1 {
routeTables[0].region = self
return &routeTables[0], nil
} else if len(routeTables) == 0 {
return nil, errors.ErrNotFound
} else {
return nil, errors.ErrDuplicateId
}
}
+22
View File
@@ -0,0 +1,22 @@
package shell
import (
"yunion.io/x/onecloud/pkg/multicloud/aws"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
func init() {
type RouteTableListOptions struct {
VpcId string `vpc id`
}
shellutils.R(&RouteTableListOptions{}, "routetable-list", "List route tables", func(cli *aws.SRegion, args *RouteTableListOptions) error {
routetables, err := cli.GetRouteTables(args.VpcId, false)
if err != nil {
printObject(err)
return nil
}
printList(routetables, 0, 0, 0, nil)
return nil
})
}
+13 -2
View File
@@ -19,6 +19,7 @@ import (
"strings"
"github.com/aws/aws-sdk-go/service/ec2"
"yunion.io/x/pkg/errors"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
@@ -131,8 +132,18 @@ func (self *SVpc) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, err
}
func (self *SVpc) GetIRouteTables() ([]cloudprovider.ICloudRouteTable, error) {
rts := []cloudprovider.ICloudRouteTable{}
return rts, nil
tables, err := self.region.GetRouteTables(self.GetId(), false)
if err != nil {
return nil, errors.Wrap(err, "SVpc.GetIRouteTables")
}
itables := make([]cloudprovider.ICloudRouteTable, len(tables))
for i := range tables {
tables[i].vpc = self
itables[i] = &tables[i]
}
return itables, nil
}
func (self *SVpc) Delete() error {