Skip to content

Commit

Permalink
Merge pull request #579 from sleungcy/i585523/v3-route-service-binding
Browse files Browse the repository at this point in the history
route service binding resource: migrate to ccv3 using go-cfclient
  • Loading branch information
sleungcy authored Jan 15, 2025
2 parents 7ef8f99 + b5649cb commit e0a7143
Showing 1 changed file with 111 additions and 34 deletions.
145 changes: 111 additions & 34 deletions cloudfoundry/resource_cf_route_service_binding.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ package cloudfoundry

import (
"context"
"log"
"strings"

"github.com/cloudfoundry/go-cfclient/v3/client"
"github.com/cloudfoundry/go-cfclient/v3/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/terraform-providers/terraform-provider-cloudfoundry/cloudfoundry/managers"

Expand All @@ -21,18 +26,32 @@ func resourceRouteServiceBinding() *schema.Resource {
StateContext: resourceRouteServiceBindingImport,
},

Schema: resourceRouteServiceBindingSchema().Schema,
SchemaVersion: 1,
StateUpgraders: []schema.StateUpgrader{
{
Type: resourceRouteServiceBindingSchema().CoreConfigSchema().ImpliedType(),
Upgrade: upgradeStateRouteServiceBindingStateV0toV1ChangeID,
Version: 0,
},
},
}
}

func resourceRouteServiceBindingSchema() *schema.Resource {
return &schema.Resource{
Schema: map[string]*schema.Schema{
"service_instance": &schema.Schema{
"service_instance": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"route": &schema.Schema{
"route": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"json_params": &schema.Schema{
"json_params": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Expand All @@ -41,15 +60,11 @@ func resourceRouteServiceBinding() *schema.Resource {
}
}

func resourceRouteServiceBindingImport(ctx context.Context, d *schema.ResourceData, meta interface{}) (res []*schema.ResourceData, err error) {
id := d.Id()
if _, _, err = parseID(id); err != nil {
return
}
func resourceRouteServiceBindingImport(ctx context.Context, d *schema.ResourceData, meta any) (res []*schema.ResourceData, err error) {
return ImportReadContext(resourceRouteServiceBindingRead)(ctx, d, meta)
}

func resourceRouteServiceBindingCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
func resourceRouteServiceBindingCreate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
session := meta.(*managers.Session)

var data map[string]interface{}
Expand All @@ -63,48 +78,110 @@ func resourceRouteServiceBindingCreate(ctx context.Context, d *schema.ResourceDa
return diag.FromErr(err)
}
}
_, err := session.ClientV2.CreateServiceBindingRoute(serviceID, routeID, data)

jobGUID, _, err := session.ClientGo.ServiceRouteBindings.Create(context.Background(), &resource.ServiceRouteBindingCreate{
Relationships: resource.ServiceRouteBindingRelationships{
// ServiceInstance ToOneRelationship `json:"service_instance"`
// // The route that the service instance is bound to
// Route ToOneRelationship `json:"route"`
ServiceInstance: resource.ToOneRelationship{
Data: &resource.Relationship{
GUID: serviceID,
},
},
Route: resource.ToOneRelationship{
Data: &resource.Relationship{
GUID: routeID,
},
},
},
})

if err != nil {
return diag.FromErr(err)
}

d.SetId(computeID(serviceID, routeID))
return nil
}

func resourceRouteServiceBindingRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
session := meta.(*managers.Session)

serviceID, routeID, err := parseID(d.Id())
if jobGUID != "" {
err = session.ClientGo.Jobs.PollComplete(context.Background(), jobGUID, nil)
}
if err != nil {
return diag.FromErr(err)
}
routes, _, err := session.ClientV2.GetServiceBindingRoutes(serviceID)

options := client.NewServiceRouteBindingListOptions()
options.ServiceInstanceGUIDs = client.Filter{Values: []string{serviceID}}
options.RouteGUIDs = client.Filter{Values: []string{routeID}}

routeBinding, err := session.ClientGo.ServiceRouteBindings.Single(context.Background(), options)

if err != nil {
return diag.FromErr(err)
}
found := false
for _, route := range routes {
if route.GUID == routeID {
found = true
break

d.SetId(routeBinding.GUID)
return nil
}

func resourceRouteServiceBindingRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
session := meta.(*managers.Session)

routeServiceBinding, err := session.ClientGo.ServiceRouteBindings.Get(context.Background(), d.Id())

if err != nil {
if strings.Contains(err.Error(), "CF-ResourceNotFound") {
d.SetId("")
return nil
}
}
if !found {
d.SetId("")
return diag.Errorf("Route '%s' not found in service instance '%s'", routeID, serviceID)
return diag.Errorf("Error when reading routeServiceBinding with id '%s': %s", d.Id(), err)
}

d.Set("service_instance", serviceID)
d.Set("route", routeID)
d.Set("service_instance", routeServiceBinding.Relationships.ServiceInstance.Data.GUID)
d.Set("route", routeServiceBinding.Relationships.Route.Data.GUID)

return nil
}

func resourceRouteServiceBindingDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
func resourceRouteServiceBindingDelete(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
session := meta.(*managers.Session)

serviceID := d.Get("service_instance").(string)
routeID := d.Get("route").(string)
_, err := session.ClientV2.DeleteServiceBindingRoute(serviceID, routeID)
jobGUID, err := session.ClientGo.ServiceRouteBindings.Delete(context.Background(), d.Id())

if err != nil {
return diag.FromErr(err)
}
if jobGUID != "" {
err = session.ClientGo.Jobs.PollComplete(context.Background(), jobGUID, nil)
}
return diag.FromErr(err)
}

func upgradeStateRouteServiceBindingStateV0toV1ChangeID(ctx context.Context, rawState map[string]any, meta any) (map[string]any, error) {
session := meta.(*managers.Session)

if len(rawState) == 0 {
log.Println("[DEBUG] Empty RouteServiceBinding; nothing to migrate.")
return rawState, nil
}

log.Printf("[DEBUG] Attributes before migration: %#v", rawState)
options := client.NewServiceRouteBindingListOptions()
options.ServiceInstanceGUIDs = client.Filter{Values: []string{rawState["service_instance"].(string)}}
options.RouteGUIDs = client.Filter{Values: []string{rawState["route"].(string)}}

routeBinding, err := session.ClientGo.ServiceRouteBindings.Single(context.Background(), options)

if err != nil {
if err == client.ErrExactlyOneResultNotReturned {
rawState["id"] = ""
return rawState, nil
}
log.Println("[DEBUG] Failed to migrate RouteServiceBinding id: error while searching for the route service binding.")
return rawState, err
}

rawState["id"] = routeBinding.GUID

log.Printf("[DEBUG] Attributes after migration: %#v", rawState)

return rawState, nil
}

0 comments on commit e0a7143

Please sign in to comment.