Skip to content

Commit 88db0a2

Browse files
Jess713Jessica Kim
andauthored
Update cf service instance test go for metadata label (#543)
* Add metadata label to cf service instance logic * Update cf service instance test go for metadata label * fix golint error in switch type assertion * update service instance doc --------- Co-authored-by: Jessica Kim <[email protected]>
1 parent 9ce1e46 commit 88db0a2

File tree

3 files changed

+122
-2
lines changed

3 files changed

+122
-2
lines changed

cloudfoundry/resource_cf_service_instance.go

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ func resourceServiceInstance() *schema.Resource {
8888
return true
8989
},
9090
},
91+
labelsKey: labelsSchema(),
92+
annotationsKey: annotationsSchema(),
9193
},
9294
CustomizeDiff: customdiff.All(
9395
customdiff.ForceNewIf(
@@ -117,6 +119,22 @@ func resourceServiceInstanceCreate(ctx context.Context, d *schema.ResourceData,
117119
space := d.Get("space").(string)
118120
jsonParameters := d.Get("json_params").(string)
119121
tags := make([]string, 0)
122+
labels := d.Get("labels").(map[string]interface{})
123+
metadata := resources.Metadata{
124+
Labels: map[string]types.NullString{},
125+
}
126+
127+
for key, label := range labels {
128+
switch v := label.(type) {
129+
case types.NullString:
130+
metadata.Labels[key] = v
131+
case string:
132+
metadata.Labels[key] = types.NullString{
133+
Value: v,
134+
IsSet: true,
135+
}
136+
}
137+
}
120138

121139
for _, v := range d.Get("tags").([]interface{}) {
122140
tags = append(tags, v.(string))
@@ -145,6 +163,7 @@ func resourceServiceInstanceCreate(ctx context.Context, d *schema.ResourceData,
145163
serviceInstance.ServicePlanGUID = servicePlan
146164
serviceInstance.Tags = tagsFormatted
147165
serviceInstance.Parameters = paramsFormatted
166+
serviceInstance.Metadata = &metadata
148167

149168
jobURL, _, err := session.ClientV3.CreateServiceInstance(serviceInstance)
150169
if err != nil {
@@ -219,6 +238,15 @@ func resourceServiceInstanceRead(ctx context.Context, d *schema.ResourceData, me
219238
d.Set("service_plan", serviceInstance.ServicePlanGUID)
220239
d.Set("space", serviceInstance.SpaceGUID)
221240

241+
labels := make(map[string]string)
242+
243+
for key, label := range serviceInstance.Metadata.Labels {
244+
if label.IsSet {
245+
labels[key] = label.Value
246+
}
247+
}
248+
d.Set("labels", labels)
249+
222250
if serviceInstance.Tags.IsSet {
223251
tags := make([]interface{}, len(serviceInstance.Tags.Value))
224252
for i, v := range serviceInstance.Tags.Value {
@@ -270,6 +298,10 @@ func resourceServiceInstanceUpdate(ctx context.Context, d *schema.ResourceData,
270298
id = d.Id()
271299
jsonParameters := d.Get("json_params").(string)
272300
space := d.Get("space").(string)
301+
labels := d.Get("labels").(map[string]interface{})
302+
metadata := resources.Metadata{
303+
Labels: map[string]types.NullString{},
304+
}
273305

274306
if len(jsonParameters) > 0 {
275307
err := json.Unmarshal([]byte(jsonParameters), &params)
@@ -280,6 +312,18 @@ func resourceServiceInstanceUpdate(ctx context.Context, d *schema.ResourceData,
280312
tags = make([]string, 0)
281313
// log.Printf("Tags : %+v", tags)
282314

315+
for key, label := range labels {
316+
switch v := label.(type) {
317+
case types.NullString:
318+
metadata.Labels[key] = v
319+
case string:
320+
metadata.Labels[key] = types.NullString{
321+
Value: v,
322+
IsSet: true,
323+
}
324+
}
325+
}
326+
283327
for _, v := range d.Get("tags").([]interface{}) {
284328
tags = append(tags, v.(string))
285329
}
@@ -304,6 +348,7 @@ func resourceServiceInstanceUpdate(ctx context.Context, d *schema.ResourceData,
304348
Name: name,
305349
Parameters: paramsFormatted,
306350
Tags: tagsFormatted,
351+
Metadata: &metadata,
307352
}
308353
// Some services don't support changing service plan, so we only add it to request body only if changed by user
309354
if d.HasChange("service_plan") {
@@ -441,5 +486,5 @@ func resourceServiceInstanceImport(ctx context.Context, d *schema.ResourceData,
441486
}
442487

443488
func isServiceInstanceUpdateRequired(d ResourceChanger) bool {
444-
return d.HasChange("name") || d.HasChange("service_plan") || d.HasChange("json_params") || d.HasChange("tags")
489+
return d.HasChange("name") || d.HasChange("service_plan") || d.HasChange("json_params") || d.HasChange("tags") || d.HasChange("labels")
445490
}

cloudfoundry/resource_cf_service_instance_test.go

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ package cloudfoundry
22

33
import (
44
"fmt"
5+
"log"
56
"testing"
67

78
"code.cloudfoundry.org/cli/api/cloudcontroller/ccv2"
89
"code.cloudfoundry.org/cli/api/cloudcontroller/ccv2/constant"
10+
"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3"
911
"github.com/terraform-providers/terraform-provider-cloudfoundry/cloudfoundry/managers"
1012

1113
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
@@ -22,6 +24,9 @@ resource "cloudfoundry_service_instance" "test-service-instance" {
2224
space = "%s"
2325
service_plan = "${data.cloudfoundry_service.test-service.service_plans["%s"]}"
2426
tags = [ "tag-1" , "tag-2" ]
27+
labels = {
28+
instance-name = "test-service-instance"
29+
}
2530
}
2631
`
2732

@@ -35,6 +40,9 @@ resource "cloudfoundry_service_instance" "test-service-instance" {
3540
space = "%s"
3641
service_plan = "${data.cloudfoundry_service.test-service.service_plans["%s"]}"
3742
tags = [ "tag-2", "tag-3", "tag-4" ]
43+
labels = {
44+
instance-name = "%s"
45+
}
3846
}
3947
`
4048

@@ -97,6 +105,7 @@ func TestAccResServiceInstance_normal(t *testing.T) {
97105

98106
spaceId, _ := defaultTestSpace(t)
99107
serviceName1, _, servicePlan := getTestServiceBrokers(t)
108+
labelVal := "new-service-label-updated"
100109

101110
ref := "cloudfoundry_service_instance.test-service-instance"
102111

@@ -125,12 +134,14 @@ func TestAccResServiceInstance_normal(t *testing.T) {
125134
ref, "tags.0", "tag-1"),
126135
resource.TestCheckResourceAttr(
127136
ref, "tags.1", "tag-2"),
137+
resource.TestCheckResourceAttr(
138+
ref, "labels.instance-name", "test-service-instance"),
128139
),
129140
},
130141

131142
resource.TestStep{
132143
Config: fmt.Sprintf(serviceInstanceResourceUpdate,
133-
serviceName1, spaceId, servicePlan,
144+
serviceName1, spaceId, servicePlan, labelVal,
134145
),
135146
Check: resource.ComposeTestCheckFunc(
136147
testAccCheckServiceInstanceExists(ref),
@@ -144,8 +155,16 @@ func TestAccResServiceInstance_normal(t *testing.T) {
144155
ref, "tags.1", "tag-3"),
145156
resource.TestCheckResourceAttr(
146157
ref, "tags.2", "tag-4"),
158+
resource.TestCheckResourceAttr(
159+
ref, "labels.instance-name", labelVal),
147160
),
148161
},
162+
resource.TestStep{
163+
Config: fmt.Sprintf(serviceInstanceResourceCreate,
164+
serviceName1, spaceId, servicePlan,
165+
),
166+
Check: testAccCheckServiceInstanceMetadataExists(ref),
167+
},
149168
},
150169
})
151170
}
@@ -186,6 +205,52 @@ func TestAccResServiceInstances_withFakePlans(t *testing.T) {
186205
})
187206
}
188207

208+
func testAccCheckServiceInstanceMetadataExists(resource string) resource.TestCheckFunc {
209+
210+
return func(s *terraform.State) error {
211+
// Retrieve the currently active session object
212+
session := testAccProvider.Meta().(*managers.Session)
213+
214+
// rs : represents the resource from Terraform statefile
215+
rs, ok := s.RootModule().Resources[resource]
216+
217+
if !ok {
218+
return fmt.Errorf("service instance '%s' not found in terraform state", resource)
219+
}
220+
221+
// It retrieves the ID of the resource from the Terraform state.
222+
GUID := rs.Primary.ID
223+
224+
serviceInstances, _, _, err := session.ClientV3.GetServiceInstances(ccv3.Query{
225+
Key: ccv3.GUIDFilter,
226+
Values: []string{GUID},
227+
})
228+
if err != nil {
229+
return err
230+
}
231+
232+
if len(serviceInstances) == 0 {
233+
return fmt.Errorf("Service instance with guid: %s not found", GUID)
234+
} else {
235+
// _ is used to ignore the i of this loop
236+
for _, instance := range serviceInstances {
237+
metadata := instance.Metadata
238+
labelVal, found := metadata.Labels["instance-name"]
239+
log.Printf("!!!! Found service instance : %+v", serviceInstances)
240+
if found {
241+
fmt.Printf("Label 'Instance-name' is: %v\n", labelVal)
242+
return nil
243+
} else {
244+
return fmt.Errorf("Label 'instance-name' does not exist in this resource\n")
245+
}
246+
}
247+
248+
}
249+
250+
return fmt.Errorf("Unexpected condition, no return hit")
251+
}
252+
}
253+
189254
func testAccCheckServiceInstanceExists(resource string) resource.TestCheckFunc {
190255

191256
return func(s *terraform.State) error {

docs/resources/service_instance.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,16 @@ The following arguments are supported:
3737
* `recursive_delete` - DEPRECATED, Since CF API v3, recursive delete is done automatically by the cloudcontroller. This will be removed in future releases.
3838
* `replace_on_params_change` - (Optional, Bool) Default: `false`. If set `true`, Cloud Foundry will replace the resource on any params change. This is useful if the service does not support parameter updates.
3939
* `replace_on_service_plan_change` - (Optional, Bool) Default: `false`. If set `true`, Cloud Foundry will replace the resource on any service plan changes. Some brokered services do not support plan changes and this allows the provider to handle those cases.
40+
* `labels` - (Optional, map string of string) Add labels as described [here](https://docs.cloudfoundry.org/adminguide/metadata.html#-view-metadata-for-an-object). Works only on cloud foundry with api >= v3.63. Below is an example usage.
41+
42+
```hcl
43+
resource "cf_service_instance" "my-cloud" {
44+
name = "service-in-my-cloud"
45+
labels = {
46+
instance-name = "service-in-my-cloud"
47+
instance-type = "my-type"
48+
}
49+
```
4050

4151
## Attributes Reference
4252

0 commit comments

Comments
 (0)