@@ -37,11 +37,14 @@ type API interface {
3737 GetAPIKey () string
3838 SetVPCServiceURLForRegion (ctx context.Context , region string ) error
3939 GetVPCs (ctx context.Context , region string ) ([]vpcv1.VPC , error )
40+ ListResourceGroups (ctx context.Context ) (* resourcemanagerv2.ResourceGroupList , error )
41+ ListServiceInstances (ctx context.Context ) ([]string , error )
4042}
4143
4244// Client makes calls to the PowerVS API.
4345type Client struct {
4446 APIKey string
47+ BXCli * BxClient
4548 managementAPI * resourcemanagerv2.ResourceManagerV2
4649 controllerAPI * resourcecontrollerv2.ResourceControllerV2
4750 vpcAPI * vpcv1.VpcV1
@@ -82,19 +85,47 @@ type DNSRecordResponse struct {
8285
8386// NewClient initializes a client with a session.
8487func NewClient () (* Client , error ) {
85- bxCli , err := NewBxClient ()
88+ bxCli , err := NewBxClient (false )
8689 if err != nil {
8790 return nil , err
8891 }
8992
9093 client := & Client {
9194 APIKey : bxCli .APIKey ,
95+ BXCli : bxCli ,
9296 }
9397
9498 if err := client .loadSDKServices (); err != nil {
9599 return nil , errors .Wrap (err , "failed to load IBM SDK services" )
96100 }
97101
102+ if bxCli .PowerVSResourceGroup == "Default" {
103+ // Here we are initialized enough to handle a default resource group
104+ ctx , cancel := context .WithTimeout (context .TODO (), 5 * time .Minute )
105+ defer cancel ()
106+
107+ resourceGroups , err := client .ListResourceGroups (ctx )
108+ if err != nil {
109+ return nil , errors .Wrap (err , "client.ListResourceGroups failed" )
110+ }
111+ if resourceGroups == nil {
112+ return nil , errors .New ("client.ListResourceGroups returns nil" )
113+ }
114+
115+ found := false
116+ for _ , resourceGroup := range resourceGroups .Resources {
117+ if resourceGroup .Default != nil && * resourceGroup .Default {
118+ bxCli .PowerVSResourceGroup = * resourceGroup .Name
119+ found = true
120+ break
121+ }
122+ }
123+
124+ if ! found {
125+ return nil , errors .New ("no default resource group found" )
126+ }
127+ }
128+
98129 return client , nil
99130}
100131
@@ -535,3 +566,83 @@ func (c *Client) GetVPCs(ctx context.Context, region string) ([]vpcv1.VPC, error
535566
536567 return vpcs .Vpcs , nil
537568}
569+
570+ // ListResourceGroups returns a list of resource groups.
571+ func (c * Client ) ListResourceGroups (ctx context.Context ) (* resourcemanagerv2.ResourceGroupList , error ) {
572+ listResourceGroupsOptions := c .managementAPI .NewListResourceGroupsOptions ()
573+
574+ resourceGroups , _ , err := c .managementAPI .ListResourceGroups (listResourceGroupsOptions )
575+ if err != nil {
576+ return nil , err
577+ }
578+
579+ return resourceGroups , err
580+ }
581+
582+ const (
583+ // resource Id for Power Systems Virtual Server in the Global catalog.
584+ powerIAASResourceID = "abd259f0-9990-11e8-acc8-b9f54a8f1661"
585+ )
586+
587+ // ListServiceInstances lists all service instances in the cloud.
588+ func (c * Client ) ListServiceInstances (ctx context.Context ) ([]string , error ) {
589+ var (
590+ serviceInstances []string
591+ options * resourcecontrollerv2.ListResourceInstancesOptions
592+ resources * resourcecontrollerv2.ResourceInstancesList
593+ err error
594+ perPage int64 = 10
595+ moreData = true
596+ nextURL * string
597+ )
598+
599+ options = c .controllerAPI .NewListResourceInstancesOptions ()
600+ options .SetResourceGroupID (c .BXCli .PowerVSResourceGroup )
601+ // resource ID for Power Systems Virtual Server in the Global catalog
602+ options .SetResourceID (powerIAASResourceID )
603+ options .SetLimit (perPage )
604+
605+ for moreData {
606+ resources , _ , err = c .controllerAPI .ListResourceInstancesWithContext (ctx , options )
607+ if err != nil {
608+ return nil , errors .Wrap (err , "Failed to list resource instance" )
609+ }
610+
611+ for _ , resource := range resources .Resources {
612+ var (
613+ getResourceOptions * resourcecontrollerv2.GetResourceInstanceOptions
614+ resourceInstance * resourcecontrollerv2.ResourceInstance
615+ response * core.DetailedResponse
616+ )
617+
618+ getResourceOptions = c .controllerAPI .NewGetResourceInstanceOptions (* resource .ID )
619+
620+ resourceInstance , response , err = c .controllerAPI .GetResourceInstance (getResourceOptions )
621+ if err != nil {
622+ return nil , errors .Wrap (err , "Failed to get instance" )
623+ }
624+ if response != nil && response .StatusCode == http .StatusNotFound || response .StatusCode == http .StatusInternalServerError {
625+ continue
626+ }
627+
628+ if resourceInstance .Type != nil && * resourceInstance .Type == "service_instance" {
629+ serviceInstances = append (serviceInstances , fmt .Sprintf ("%s %s" , * resource .Name , * resource .GUID ))
630+ }
631+ }
632+
633+ // Based on: https://cloud.ibm.com/apidocs/resource-controller/resource-controller?code=go#list-resource-instances
634+ nextURL , err = core .GetQueryParam (resources .NextURL , "start" )
635+ if err != nil {
636+ return nil , errors .Wrap (err , "Failed to GetQueryParam on start" )
637+ }
638+ if nextURL == nil {
639+ options .SetStart ("" )
640+ } else {
641+ options .SetStart (* nextURL )
642+ }
643+
644+ moreData = * resources .RowsCount == perPage
645+ }
646+
647+ return serviceInstances , nil
648+ }
0 commit comments