55 "errors"
66 "fmt"
77 "net/http"
8+ "strings"
89 "time"
910
1011 "github.com/IBM-Cloud/bluemix-go/crn"
@@ -14,6 +15,7 @@ import (
1415 "github.com/IBM/networking-go-sdk/dnssvcsv1"
1516 "github.com/IBM/networking-go-sdk/dnszonesv1"
1617 "github.com/IBM/networking-go-sdk/resourcerecordsv1"
18+ "github.com/IBM/networking-go-sdk/transitgatewayapisv1"
1719 "github.com/IBM/networking-go-sdk/zonesv1"
1820 "github.com/IBM/platform-services-go-sdk/iamidentityv1"
1921 "github.com/IBM/platform-services-go-sdk/resourcecontrollerv2"
@@ -42,16 +44,19 @@ type API interface {
4244 ListServiceInstances (ctx context.Context ) ([]string , error )
4345 ServiceInstanceGUIDToName (ctx context.Context , id string ) (string , error )
4446 GetDatacenterCapabilities (ctx context.Context , region string ) (map [string ]bool , error )
47+ GetAttachedTransitGateway (ctx context.Context , svcInsID string ) (string , error )
48+ GetTGConnectionVPC (ctx context.Context , gatewayID string , vpcSubnetID string ) (string , error )
4549}
4650
4751// Client makes calls to the PowerVS API.
4852type Client struct {
49- APIKey string
50- BXCli * BxClient
51- managementAPI * resourcemanagerv2.ResourceManagerV2
52- controllerAPI * resourcecontrollerv2.ResourceControllerV2
53- vpcAPI * vpcv1.VpcV1
54- dnsServicesAPI * dnssvcsv1.DnsSvcsV1
53+ APIKey string
54+ BXCli * BxClient
55+ managementAPI * resourcemanagerv2.ResourceManagerV2
56+ controllerAPI * resourcecontrollerv2.ResourceControllerV2
57+ vpcAPI * vpcv1.VpcV1
58+ dnsServicesAPI * dnssvcsv1.DnsSvcsV1
59+ transitGatewayAPI * transitgatewayapisv1.TransitGatewayApisV1
5560}
5661
5762// cisServiceID is the Cloud Internet Services' catalog service ID.
@@ -138,6 +143,7 @@ func (c *Client) loadSDKServices() error {
138143 c .loadResourceControllerAPI ,
139144 c .loadVPCV1API ,
140145 c .loadDNSServicesAPI ,
146+ c .loadTransitGatewayAPI ,
141147 }
142148
143149 // Call all the load functions.
@@ -504,6 +510,22 @@ func (c *Client) loadDNSServicesAPI() error {
504510 return nil
505511}
506512
513+ func (c * Client ) loadTransitGatewayAPI () error {
514+ authenticator := & core.IamAuthenticator {
515+ ApiKey : c .APIKey ,
516+ }
517+ versionDate := "2023-07-04"
518+ tgSvc , err := transitgatewayapisv1 .NewTransitGatewayApisV1 (& transitgatewayapisv1.TransitGatewayApisV1Options {
519+ Authenticator : authenticator ,
520+ Version : & versionDate ,
521+ })
522+ if err != nil {
523+ return err
524+ }
525+ c .transitGatewayAPI = tgSvc
526+ return nil
527+ }
528+
507529// SetVPCServiceURLForRegion will set the VPC Service URL to a specific IBM Cloud Region, in order to access Region scoped resources
508530func (c * Client ) SetVPCServiceURLForRegion (ctx context.Context , region string ) error {
509531 regionOptions := c .vpcAPI .NewGetRegionOptions (region )
@@ -663,12 +685,6 @@ func (c *Client) ListServiceInstances(ctx context.Context) ([]string, error) {
663685 return serviceInstances , nil
664686}
665687
666- // TransitGatewayEnabledZone returns if a zone is configured for transit gateways rather than cloud connections.
667- func TransitGatewayEnabledZone (zone string ) bool {
668- // @TBD - HACK. Waiting for officially supported detection function
669- return zone == "dal10"
670- }
671-
672688// ServiceInstanceGUIDToName returns the name of the matching service instance GUID which was passed in.
673689func (c * Client ) ServiceInstanceGUIDToName (ctx context.Context , id string ) (string , error ) {
674690 var (
@@ -765,3 +781,111 @@ func (c *Client) GetDatacenterCapabilities(ctx context.Context, region string) (
765781 }
766782 return getOk .Payload .Capabilities , nil
767783}
784+
785+ // GetAttachedTransitGateway finds an existing Transit Gateway attached to the provided PowerVS cloud instance.
786+ func (c * Client ) GetAttachedTransitGateway (ctx context.Context , svcInsID string ) (string , error ) {
787+ var (
788+ gateways []transitgatewayapisv1.TransitGateway
789+ gateway transitgatewayapisv1.TransitGateway
790+ err error
791+ conns []transitgatewayapisv1.TransitConnection
792+ conn transitgatewayapisv1.TransitConnection
793+ )
794+ gateways , err = c .getTransitGateways (ctx )
795+ if err != nil {
796+ return "" , err
797+ }
798+ for _ , gateway = range gateways {
799+ conns , err = c .getTransitConnections (ctx , * gateway .ID )
800+ if err != nil {
801+ return "" , err
802+ }
803+ for _ , conn = range conns {
804+ if * conn .NetworkType == "power_virtual_server" && strings .Contains (* conn .NetworkID , svcInsID ) {
805+ return * conn .TransitGateway .ID , nil
806+ }
807+ }
808+ }
809+ return "" , nil
810+ }
811+
812+ // GetTGConnectionVPC checks if the VPC subnet is attached to the provided Transit Gateway.
813+ func (c * Client ) GetTGConnectionVPC (ctx context.Context , gatewayID string , vpcSubnetID string ) (string , error ) {
814+ conns , err := c .getTransitConnections (ctx , gatewayID )
815+ if err != nil {
816+ return "" , err
817+ }
818+ for _ , conn := range conns {
819+ if * conn .NetworkType == "vpc" && strings .Contains (* conn .NetworkID , vpcSubnetID ) {
820+ return * conn .ID , nil
821+ }
822+ }
823+ return "" , nil
824+ }
825+
826+ func (c * Client ) getTransitGateways (ctx context.Context ) ([]transitgatewayapisv1.TransitGateway , error ) {
827+ var (
828+ listTransitGatewaysOptions * transitgatewayapisv1.ListTransitGatewaysOptions
829+ gatewayCollection * transitgatewayapisv1.TransitGatewayCollection
830+ response * core.DetailedResponse
831+ err error
832+ perPage int64 = 32
833+ moreData = true
834+ )
835+
836+ listTransitGatewaysOptions = c .transitGatewayAPI .NewListTransitGatewaysOptions ()
837+ listTransitGatewaysOptions .Limit = & perPage
838+
839+ result := []transitgatewayapisv1.TransitGateway {}
840+
841+ for moreData {
842+ // https://github.com/IBM/networking-go-sdk/blob/master/transitgatewayapisv1/transit_gateway_apis_v1.go#L184
843+ gatewayCollection , response , err = c .transitGatewayAPI .ListTransitGatewaysWithContext (ctx , listTransitGatewaysOptions )
844+ if err != nil {
845+ return nil , fmt .Errorf ("failed to list transit gateways: %w and the respose is: %s" , err , response )
846+ }
847+
848+ result = append (result , gatewayCollection .TransitGateways ... )
849+
850+ if gatewayCollection .Next != nil {
851+ listTransitGatewaysOptions .SetStart (* gatewayCollection .Next .Start )
852+ }
853+
854+ moreData = gatewayCollection .Next != nil
855+ }
856+
857+ return result , nil
858+ }
859+
860+ func (c * Client ) getTransitConnections (ctx context.Context , tgID string ) ([]transitgatewayapisv1.TransitConnection , error ) {
861+ var (
862+ listConnectionsOptions * transitgatewayapisv1.ListConnectionsOptions
863+ connectionCollection * transitgatewayapisv1.TransitConnectionCollection
864+ response * core.DetailedResponse
865+ err error
866+ perPage int64 = 32
867+ moreData = true
868+ )
869+
870+ listConnectionsOptions = c .transitGatewayAPI .NewListConnectionsOptions ()
871+ listConnectionsOptions .Limit = & perPage
872+
873+ result := []transitgatewayapisv1.TransitConnection {}
874+
875+ for moreData {
876+ connectionCollection , response , err = c .transitGatewayAPI .ListConnectionsWithContext (ctx , listConnectionsOptions )
877+ if err != nil {
878+ return nil , fmt .Errorf ("failed to list transit gateways: %w and the respose is: %s" , err , response )
879+ }
880+
881+ result = append (result , connectionCollection .Connections ... )
882+
883+ if connectionCollection .Next != nil {
884+ listConnectionsOptions .SetStart (* connectionCollection .Next .Start )
885+ }
886+
887+ moreData = connectionCollection .Next != nil
888+ }
889+
890+ return result , nil
891+ }
0 commit comments