Skip to content

Feature/import service instance sharing #265

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -268,3 +268,70 @@ interactions:
status: 204 No Content
code: 204
duration: 204.222897ms
- id: 4
request:
proto: HTTP/1.1
proto_major: 1
proto_minor: 1
content_length: 0
transfer_encoding: [ ]
trailer: { }
host: api.x.x.x.x.com
remote_addr: ""
request_uri: ""
body: ""
form: { }
headers:
Authorization:
- Bearer redacted
User-Agent:
- Go-CF-Client/3.0
url: https://api.x.x.x.x.com/v3/service_instances/5e2976bb-332e-41e1-8be3-53baafea9296/shared_spaces
method: GET
response:
proto: HTTP/2.0
proto_major: 2
proto_minor: 0
transfer_encoding: [ ]
trailer: { }
content_length: -1
uncompressed: false
body: '{"data":[{"guid":"02c0cc92-6ecc-44b1-b7b2-096ca19ee143"}, {"guid":"121c3a95-0f82-45a6-8ff2-1920b2067edb"}]}'
headers:
Content-Type:
- application/json; charset=utf-8
Date:
- Mon, 25 Mar 2024 10:39:34 GMT
Referrer-Policy:
- strict-origin-when-cross-origin
Server:
- nginx
Strict-Transport-Security:
- max-age=31536000; includeSubDomains; preload;
X-B3-Spanid:
- 7031327687a56f81
X-B3-Traceid:
- de8d237a1f2045057031327687a56f81
X-Content-Type-Options:
- nosniff
X-Download-Options:
- noopen
X-Frame-Options:
- SAMEORIGIN
X-Permitted-Cross-Domain-Policies:
- none
X-Ratelimit-Limit:
- "20000"
X-Ratelimit-Remaining:
- "18000"
X-Ratelimit-Reset:
- "1711364588"
X-Runtime:
- "0.058984"
X-Vcap-Request-Id:
- de8d237a-1f20-4505-7031-327687a56f81::f3bea4eb-8c5a-432a-8d19-f256a2758e80
X-Xss-Protection:
- 1; mode=block
status: 200 OK
code: 200
duration: 225.980057ms
28 changes: 24 additions & 4 deletions cloudfoundry/provider/resource_service_instance_sharing.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package provider
import (
"context"
"fmt"
"github.com/hashicorp/terraform-plugin-framework/path"

"github.com/cloudfoundry/terraform-provider-cloudfoundry/internal/validation"
"github.com/hashicorp/terraform-plugin-framework-validators/setvalidator"
Expand Down Expand Up @@ -45,6 +46,7 @@ func (r *serviceInstanceSharingResource) Schema(ctx context.Context, req resourc
MarkdownDescription: "Provides a resource for managing service instance sharing in Cloud Foundry.",

Attributes: map[string]schema.Attribute{
idKey: guidSchema(),
"service_instance": schema.StringAttribute{
MarkdownDescription: "The ID of the service instance to share.",
Required: true,
Expand Down Expand Up @@ -108,8 +110,10 @@ func (r *serviceInstanceSharingResource) Create(ctx context.Context, req resourc
resp.Diagnostics.AddError("Error sharing service instance with spaces", err.Error())
return
}

tflog.Trace(ctx, "created a service instance sharing resource")
newState := ServiceInstanceSharingType{
Id: plan.ServiceInstance,
ServiceInstance: plan.ServiceInstance,
Spaces: plan.Spaces,
}
Expand All @@ -126,13 +130,19 @@ func (r *serviceInstanceSharingResource) Read(ctx context.Context, req resource.
return
}

relationship, err := r.cfClient.ServiceInstances.GetSharedSpaceRelationships(ctx, data.ServiceInstance.ValueString())
serviceInstanceID := data.Id.ValueString()

if serviceInstanceID == "" {
serviceInstanceID = data.ServiceInstance.ValueString()
}

relationship, err := r.cfClient.ServiceInstances.GetSharedSpaceRelationships(ctx, serviceInstanceID)
if err != nil {
resp.Diagnostics.AddError("Error when getting shared spaces for service instance", err.Error())
return
}

data = mapSharedSpacesValuesToType(relationship, data.ServiceInstance.ValueString())
data = mapSharedSpacesValuesToType(relationship, serviceInstanceID)

tflog.Trace(ctx, "read a service instance sharing resource")

Expand All @@ -145,7 +155,6 @@ func (r *serviceInstanceSharingResource) Update(ctx context.Context, req resourc
}

func (r *serviceInstanceSharingResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {

var state ServiceInstanceSharingType

diags := req.State.Get(ctx, &state)
Expand All @@ -162,7 +171,13 @@ func (r *serviceInstanceSharingResource) Delete(ctx context.Context, req resourc
return
}

err := r.cfClient.ServiceInstances.UnShareWithSpaces(ctx, state.ServiceInstance.ValueString(), spaces)
serviceInstanceID := state.Id.ValueString()

if serviceInstanceID == "" {
serviceInstanceID = state.ServiceInstance.ValueString()
}

err := r.cfClient.ServiceInstances.UnShareWithSpaces(ctx, serviceInstanceID, spaces)

if err != nil {
resp.Diagnostics.AddError("Error unsharing service instance with spaces", err.Error())
Expand All @@ -179,7 +194,12 @@ func mapSharedSpacesValuesToType(relationship *cfv3resource.ServiceInstanceShare
}
s := types.SetValueMust(types.StringType, sharedSpaces)
return ServiceInstanceSharingType{
Id: types.StringValue(serviceInstance),
ServiceInstance: types.StringValue(serviceInstance),
Spaces: s,
}
}

func (r *serviceInstanceSharingResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
}
40 changes: 40 additions & 0 deletions cloudfoundry/provider/resource_service_instance_sharing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ func TestMapSharedSpacesValuesToType(t *testing.T) {
}
spaces := types.SetValueMust(types.StringType, sharedSpaces)
expected := ServiceInstanceSharingType{
Id: types.StringValue(serviceInstance),
ServiceInstance: types.StringValue(serviceInstance),
Spaces: spaces,
}
Expand All @@ -143,3 +144,42 @@ func TestMapSharedSpacesValuesToType(t *testing.T) {

assert.Equal(t, expected, result)
}

func TestServiceInstanceSharingResource_Import(t *testing.T) {
var (
testUserProvidedServiceInstanceGUID = "5e2976bb-332e-41e1-8be3-53baafea9296"
testSpaces = `["02c0cc92-6ecc-44b1-b7b2-096ca19ee143", "121c3a95-0f82-45a6-8ff2-1920b2067edb"]`
)
t.Parallel()

// setup
resourceName := "cloudfoundry_service_instance_sharing.rs"
cfg := getCFHomeConf()
rec := cfg.SetupVCR(t, "fixtures/resource_service_instance_sharing")
defer stopQuietly(rec)

// actual test
resource.Test(t, resource.TestCase{
IsUnitTest: true,
ProtoV6ProviderFactories: getProviders(rec.GetDefaultClient()),
Steps: []resource.TestStep{
{
Config: hclProvider(nil) + hclResourceServiceInstanceSharing(&ServiceInstanceSharingResourceModelPtr{
HclType: hclObjectResource,
HclObjectName: "rs",
ServiceInstance: strtostrptr(testUserProvidedServiceInstanceGUID),
Spaces: &testSpaces,
}),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestMatchResourceAttr(resourceName, "service_instance", regexpValidUUID),
resource.TestMatchResourceAttr(resourceName, "spaces.0", regexpValidUUID),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}
1 change: 1 addition & 0 deletions cloudfoundry/provider/types_service_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ type maintenanceInfoType struct {
}

type ServiceInstanceSharingType struct {
Id types.String `tfsdk:"id"`
ServiceInstance types.String `tfsdk:"service_instance"`
Spaces types.Set `tfsdk:"spaces"`
}
Expand Down
22 changes: 22 additions & 0 deletions docs/resources/service_instance_sharing.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,25 @@ resource "cloudfoundry_service_instance_sharing" "instance_sharing" {
- `service_instance` (String) The ID of the service instance to share.
- `spaces` (Set of String) The IDs of the spaces to share the service instance with.

### Read-Only

- `id` (String) The GUID of the object. This will be the same as the service_instance GUID.

## Import

Import is supported using the following syntax:

```terraform
# terraform import cloudfoundry_service_instance_sharing.<resource_name> <service_instance_guid>

terraform import cloudfoundry_service_instance_sharing.my_instance_sharing a1b2c3d4-5678-90ab-cdef-12345678abcd
```

For Terraform 1.5+ users, you can also use the newer import blocks syntax:

```terraform
import {
to = cloudfoundry_service_instance_sharing.my_instance_sharing
id = "a1b2c3d4-5678-90ab-cdef-12345678abcd"
}
```