diff --git a/cf.go b/cf.go index 554fff1..8e6b985 100644 --- a/cf.go +++ b/cf.go @@ -8,9 +8,10 @@ import ( "github.com/cloudfoundry-community/go-cfclient/v3/resource" ) -type NameResolver interface { - getOrganizationName(organizationGUID string) (string, error) - getSpaceName(spaceGUID string) (string, error) +type ResourceGetter interface { + getOrganization(organizationGUID string) (*resource.Organization, error) + getSpace(spaceGUID string) (*resource.Space, error) + getServiceInstance(instanceGUID string) (*resource.ServiceInstance, error) } type OrganizationGetter interface { @@ -21,16 +22,21 @@ type SpaceGetter interface { Get(ctx context.Context, guid string) (*resource.Space, error) } -type cfNameResolver struct { - Organizations OrganizationGetter - Spaces SpaceGetter +type ServiceInstanceGetter interface { + Get(ctx context.Context, guid string) (*resource.ServiceInstance, error) } -func newCFNameResolver( +type cfResourceGetter struct { + Organizations OrganizationGetter + Spaces SpaceGetter + ServiceInstances ServiceInstanceGetter +} + +func newCFResourceGetter( cfApiUrl string, cfApiClientId string, cfApiClientSecret string, -) (*cfNameResolver, error) { +) (*cfResourceGetter, error) { cfg, err := config.NewClientSecret( cfApiUrl, cfApiClientId, @@ -43,24 +49,33 @@ func newCFNameResolver( if err != nil { return nil, err } - return &cfNameResolver{ - Organizations: cf.Organizations, - Spaces: cf.Spaces, + return &cfResourceGetter{ + Organizations: cf.Organizations, + Spaces: cf.Spaces, + ServiceInstances: cf.ServiceInstances, }, nil } -func (c *cfNameResolver) getOrganizationName(organizationGUID string) (string, error) { +func (c *cfResourceGetter) getOrganization(organizationGUID string) (*resource.Organization, error) { organization, err := c.Organizations.Get(context.Background(), organizationGUID) if err != nil { - return "", err + return nil, err } - return organization.Name, nil + return organization, nil } -func (c *cfNameResolver) getSpaceName(spaceGUID string) (string, error) { +func (c *cfResourceGetter) getSpace(spaceGUID string) (*resource.Space, error) { space, err := c.Spaces.Get(context.Background(), spaceGUID) if err != nil { - return "", err + return nil, err + } + return space, nil +} + +func (c *cfResourceGetter) getServiceInstance(instanceGUID string) (*resource.ServiceInstance, error) { + instance, err := c.ServiceInstances.Get(context.Background(), instanceGUID) + if err != nil { + return nil, err } - return space.Name, nil + return instance, nil } diff --git a/cf_test.go b/cf_test.go index fad0747..2f20ff7 100644 --- a/cf_test.go +++ b/cf_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/cloudfoundry-community/go-cfclient/v3/resource" + "github.com/google/go-cmp/cmp" ) type mockOrganizations struct { @@ -45,28 +46,48 @@ func (s *mockSpaces) Get(ctx context.Context, guid string) (*resource.Space, err }, nil } -func TestGetOrganizationName(t *testing.T) { +type mockServiceInstances struct { + getServiceInstanceErr error + instanceName string + instanceGUID string +} + +func (si *mockServiceInstances) Get(ctx context.Context, guid string) (*resource.ServiceInstance, error) { + if si.getServiceInstanceErr != nil { + return nil, si.getServiceInstanceErr + } + if guid != si.instanceGUID { + return nil, fmt.Errorf("guid argument: %s does not match expected guid: %s", guid, si.instanceGUID) + } + return &resource.ServiceInstance{ + Name: si.instanceName, + }, nil +} + +func TestGetOrganization(t *testing.T) { testCases := map[string]struct { - cfClientWrapper *cfNameResolver - expectedOrganizationName string - expectedErr error - organizationGuid string + cfResourceGetter *cfResourceGetter + expectedOrganization *resource.Organization + expectedErr error + organizationGuid string }{ "success": { - cfClientWrapper: &cfNameResolver{ + cfResourceGetter: &cfResourceGetter{ Organizations: &mockOrganizations{ organizationName: "org-1", organizationGuid: "guid-1", }, - Spaces: &mockSpaces{}, }, - organizationGuid: "guid-1", - expectedOrganizationName: "org-1", + organizationGuid: "guid-1", + expectedOrganization: &resource.Organization{ + Name: "org-1", + }, }, "error": { - cfClientWrapper: &cfNameResolver{ - Organizations: &mockOrganizations{}, - Spaces: &mockSpaces{}, + cfResourceGetter: &cfResourceGetter{ + Organizations: &mockOrganizations{ + getOrganizationErr: errors.New("error getting organization"), + }, }, expectedErr: errors.New("error getting organization"), }, @@ -74,38 +95,39 @@ func TestGetOrganizationName(t *testing.T) { for name, test := range testCases { t.Run(name, func(t *testing.T) { - organizationName, err := test.cfClientWrapper.getOrganizationName(test.organizationGuid) - if organizationName != test.expectedOrganizationName { - t.Fatalf("expected organization name: %s, got: %s", test.expectedOrganizationName, organizationName) + organization, err := test.cfResourceGetter.getOrganization(test.organizationGuid) + if !cmp.Equal(organization, test.expectedOrganization) { + t.Errorf(cmp.Diff(organization, test.expectedOrganization)) } - if err != nil && err.Error() != test.expectedErr.Error() { + if (test.expectedErr != nil && err == nil) || + (err != nil && err.Error() != test.expectedErr.Error()) { t.Fatalf("expected error: %s, got: %s", test.expectedErr, err) } }) } } -func TestGetSpaceName(t *testing.T) { +func TestGetSpace(t *testing.T) { testCases := map[string]struct { - cfClientWrapper *cfNameResolver - expectedSpaceName string - expectedErr error - spaceGuid string + cfResourceGetter *cfResourceGetter + expectedSpace *resource.Space + expectedErr error + spaceGuid string }{ "success": { - cfClientWrapper: &cfNameResolver{ - Organizations: &mockOrganizations{}, + cfResourceGetter: &cfResourceGetter{ Spaces: &mockSpaces{ - spaceName: "plan-1", + spaceName: "space-1", spaceGuid: "guid-1", }, }, - spaceGuid: "guid-1", - expectedSpaceName: "plan-1", + spaceGuid: "guid-1", + expectedSpace: &resource.Space{ + Name: "space-1", + }, }, "error": { - cfClientWrapper: &cfNameResolver{ - Organizations: &mockOrganizations{}, + cfResourceGetter: &cfResourceGetter{ Spaces: &mockSpaces{ getSpaceErr: errors.New("error getting space"), }, @@ -116,11 +138,55 @@ func TestGetSpaceName(t *testing.T) { for name, test := range testCases { t.Run(name, func(t *testing.T) { - spaceName, err := test.cfClientWrapper.getSpaceName(test.spaceGuid) - if spaceName != test.expectedSpaceName { - t.Fatalf("expected space name: %s, got: %s", test.expectedSpaceName, spaceName) + space, err := test.cfResourceGetter.getSpace(test.spaceGuid) + if !cmp.Equal(space, test.expectedSpace) { + t.Errorf(cmp.Diff(space, test.expectedSpace)) + } + if (test.expectedErr != nil && err == nil) || + (err != nil && err.Error() != test.expectedErr.Error()) { + t.Fatalf("expected error: %s, got: %s", test.expectedErr, err) + } + }) + } +} + +func TestGetServiceInstance(t *testing.T) { + testCases := map[string]struct { + cfResourceGetter *cfResourceGetter + expectedServiceInstance *resource.ServiceInstance + expectedErr error + instanceGUID string + }{ + "success": { + cfResourceGetter: &cfResourceGetter{ + ServiceInstances: &mockServiceInstances{ + instanceName: "instance-1", + instanceGUID: "guid-1", + }, + }, + instanceGUID: "guid-1", + expectedServiceInstance: &resource.ServiceInstance{ + Name: "instance-1", + }, + }, + "error": { + cfResourceGetter: &cfResourceGetter{ + ServiceInstances: &mockServiceInstances{ + getServiceInstanceErr: errors.New("error getting instance"), + }, + }, + expectedErr: errors.New("error getting instance"), + }, + } + + for name, test := range testCases { + t.Run(name, func(t *testing.T) { + instance, err := test.cfResourceGetter.getServiceInstance(test.instanceGUID) + if !cmp.Equal(instance, test.expectedServiceInstance) { + t.Errorf(cmp.Diff(instance, test.expectedServiceInstance)) } - if err != nil && err.Error() != test.expectedErr.Error() { + if (test.expectedErr != nil && err == nil) || + (err != nil && err.Error() != test.expectedErr.Error()) { t.Fatalf("expected error: %s, got: %s", test.expectedErr, err) } }) diff --git a/tags.go b/tags.go index 245a57e..3986a13 100644 --- a/tags.go +++ b/tags.go @@ -3,6 +3,8 @@ package brokertags import ( "strings" "time" + + "github.com/cloudfoundry-community/go-cfclient/v3/resource" ) const ( @@ -21,27 +23,27 @@ const ( type TagManager interface { GenerateTags( action Action, - environment string, serviceName string, servicePlanName string, - organizationGUID string, - spaceGUID string, - instanceGUID string, + resourceGUIDs ResourceGUIDs, + getMissingResources bool, ) (map[string]string, error) } type CfTagManager struct { - broker string - cfNameResolver NameResolver + broker string + environment string + cfResourceGetter ResourceGetter } func NewCFTagManager( broker string, + environment string, cfApiUrl string, cfApiClientId string, cfApiClientSecret string, ) (*CfTagManager, error) { - cfNameResolver, err := newCFNameResolver( + cfResourceGetter, err := newCFResourceGetter( cfApiUrl, cfApiClientId, cfApiClientSecret, @@ -51,18 +53,23 @@ func NewCFTagManager( } return &CfTagManager{ broker, - cfNameResolver, + environment, + cfResourceGetter, }, nil } +type ResourceGUIDs struct { + InstanceGUID string + SpaceGUID string + OrganizationGUID string +} + func (t *CfTagManager) GenerateTags( action Action, - environment string, serviceName string, planName string, - organizationGUID string, - spaceGUID string, - instanceGUID string, + resourceGUIDs ResourceGUIDs, + getMissingResources bool, ) (map[string]string, error) { tags := make(map[string]string) @@ -74,8 +81,8 @@ func (t *CfTagManager) GenerateTags( tags[BrokerTagKey] = t.broker } - if environment != "" { - tags[EnvironmentTagKey] = strings.ToLower(environment) + if t.environment != "" { + tags[EnvironmentTagKey] = strings.ToLower(t.environment) } if serviceName != "" { @@ -86,29 +93,76 @@ func (t *CfTagManager) GenerateTags( tags[ServicePlanName] = planName } - if organizationGUID != "" { - tags[OrganizationGUIDTagKey] = organizationGUID + if resourceGUIDs.InstanceGUID != "" { + tags[ServiceInstanceGUIDTagKey] = resourceGUIDs.InstanceGUID + } - organizationName, err := t.cfNameResolver.getOrganizationName(organizationGUID) + var ( + spaceGUID string + space *resource.Space + organizationGUID string + organization *resource.Organization + err error + ) + + spaceGUID = resourceGUIDs.SpaceGUID + if spaceGUID == "" && getMissingResources { + spaceGUID, err = t.getSpaceGuid(resourceGUIDs.InstanceGUID) if err != nil { return nil, err } - tags[OrganizationNameTagKey] = organizationName } if spaceGUID != "" { tags[SpaceGUIDTagKey] = spaceGUID + } - spaceName, err := t.cfNameResolver.getSpaceName(spaceGUID) + if spaceGUID != "" && space == nil { + space, err = t.cfResourceGetter.getSpace(spaceGUID) if err != nil { return nil, err } - tags[SpaceNameTagKey] = spaceName } - if instanceGUID != "" { - tags[ServiceInstanceGUIDTagKey] = instanceGUID + if space != nil { + tags[SpaceNameTagKey] = space.Name + } + + organizationGUID = resourceGUIDs.OrganizationGUID + if organizationGUID == "" && getMissingResources { + organizationGUID = t.getOrganizationGuidFromSpace(space) + } + + if organizationGUID != "" { + tags[OrganizationGUIDTagKey] = organizationGUID + } + + if organizationGUID != "" && organization == nil { + organization, err = t.cfResourceGetter.getOrganization(organizationGUID) + if err != nil { + return nil, err + } + } + + if organization != nil { + tags[OrganizationNameTagKey] = organization.Name } return tags, nil } + +func (t *CfTagManager) getSpaceGuid(instanceGUID string) (string, error) { + instance, err := t.cfResourceGetter.getServiceInstance(instanceGUID) + if err != nil { + return "", err + } + spaceGUID := instance.Relationships.Space.Data.GUID + return spaceGUID, nil +} + +func (t *CfTagManager) getOrganizationGuidFromSpace(space *resource.Space) string { + if space == nil { + return "" + } + return space.Relationships.Organization.Data.GUID +} diff --git a/tags_test.go b/tags_test.go index 7580f3d..3cce4cf 100644 --- a/tags_test.go +++ b/tags_test.go @@ -4,62 +4,101 @@ import ( "errors" "testing" + "github.com/cloudfoundry-community/go-cfclient/v3/resource" "github.com/google/go-cmp/cmp" ) type mockCFClientWrapper struct { - getOrganizationErr error - organizationName string - getSpaceErr error - spaceName string - spaceGUID string - organizationGUID string - instanceGUID string + getOrganizationErr error + organizationName string + getSpaceErr error + spaceName string + getServiceInstanceErr error + instanceName string + spaceGUID string + organizationGUID string + instanceGUID string + getServiceInstanceCallCount int + getSpaceInstanceCallCount int } -func (m *mockCFClientWrapper) getOrganizationName(organizationGUID string) (string, error) { +func (m *mockCFClientWrapper) getOrganization(organizationGUID string) (*resource.Organization, error) { if m.getOrganizationErr != nil { - return "", m.getOrganizationErr + return nil, m.getOrganizationErr } if m.organizationGUID != "" && m.organizationGUID != organizationGUID { - return "", errors.New("organization GUID does not match expected value") + return nil, errors.New("organization GUID does not match expected value") } - return m.organizationName, nil + return &resource.Organization{ + Name: m.organizationName, + }, nil } -func (m *mockCFClientWrapper) getSpaceName(spaceGUID string) (string, error) { +func (m *mockCFClientWrapper) getSpace(spaceGUID string) (*resource.Space, error) { + m.getSpaceInstanceCallCount++ if m.getSpaceErr != nil { - return "", m.getSpaceErr + return nil, m.getSpaceErr } if m.spaceGUID != "" && m.spaceGUID != spaceGUID { - return "", errors.New("space GUID does not match expected value") + return nil, errors.New("space GUID does not match expected value") } - return m.spaceName, nil + return &resource.Space{ + Name: m.spaceName, + Relationships: &resource.SpaceRelationships{ + Organization: &resource.ToOneRelationship{ + Data: &resource.Relationship{ + GUID: m.organizationGUID, + }, + }, + }, + }, nil +} + +func (m *mockCFClientWrapper) getServiceInstance(instanceGUID string) (*resource.ServiceInstance, error) { + m.getServiceInstanceCallCount++ + if m.getServiceInstanceErr != nil { + return nil, m.getServiceInstanceErr + } + if m.instanceGUID != "" && m.instanceGUID != instanceGUID { + return nil, errors.New("instance GUID does not match expected value") + } + return &resource.ServiceInstance{ + Name: m.instanceName, + Relationships: resource.ServiceInstanceRelationships{ + Space: &resource.ToOneRelationship{ + Data: &resource.Relationship{ + GUID: m.spaceGUID, + }, + }, + }, + }, nil } func TestGenerateTags(t *testing.T) { testCases := map[string]struct { - tagManager *CfTagManager - expectedTags map[string]string - action Action - environment string - serviceOfferingName string - servicePlanName string - organizationGUID string - spaceGUID string - instanceGUID string + tagManager *CfTagManager + expectedTags map[string]string + action Action + serviceOfferingName string + servicePlanName string + resourceGUIDS ResourceGUIDs + getMissingResources bool + expectedGetServiceInstanceCallCount int + expectedGetSpaceInstanceCallCount int }{ "Create": { action: Create, serviceOfferingName: "abc1", servicePlanName: "abc2", - organizationGUID: "abc3", - spaceGUID: "abc4", - instanceGUID: "abc5", - environment: "testing", + resourceGUIDS: ResourceGUIDs{ + OrganizationGUID: "abc3", + SpaceGUID: "abc4", + InstanceGUID: "abc5", + }, tagManager: &CfTagManager{ - broker: "AWS Broker", - cfNameResolver: &mockCFClientWrapper{ + broker: "AWS Broker", + environment: "testing", + cfResourceGetter: &mockCFClientWrapper{ organizationName: "org-1", spaceName: "space-1", spaceGUID: "abc4", @@ -67,6 +106,7 @@ func TestGenerateTags(t *testing.T) { instanceGUID: "abc5", }, }, + expectedGetSpaceInstanceCallCount: 1, expectedTags: map[string]string{ "client": "Cloud Foundry", "broker": "AWS Broker", @@ -84,13 +124,15 @@ func TestGenerateTags(t *testing.T) { action: Update, serviceOfferingName: "abc1", servicePlanName: "abc2", - organizationGUID: "abc3", - spaceGUID: "abc4", - instanceGUID: "abc5", - environment: "testing", + resourceGUIDS: ResourceGUIDs{ + OrganizationGUID: "abc3", + SpaceGUID: "abc4", + InstanceGUID: "abc5", + }, tagManager: &CfTagManager{ - broker: "AWS Broker", - cfNameResolver: &mockCFClientWrapper{ + broker: "AWS Broker", + environment: "testing", + cfResourceGetter: &mockCFClientWrapper{ organizationName: "org-1", spaceName: "space-1", spaceGUID: "abc4", @@ -98,6 +140,7 @@ func TestGenerateTags(t *testing.T) { instanceGUID: "abc5", }, }, + expectedGetSpaceInstanceCallCount: 1, expectedTags: map[string]string{ "client": "Cloud Foundry", "broker": "AWS Broker", @@ -115,12 +158,14 @@ func TestGenerateTags(t *testing.T) { action: Create, serviceOfferingName: "abc1", servicePlanName: "abc2", - organizationGUID: "abc3", - spaceGUID: "abc4", - instanceGUID: "abc5", - environment: "", + resourceGUIDS: ResourceGUIDs{ + OrganizationGUID: "abc3", + SpaceGUID: "abc4", + InstanceGUID: "abc5", + }, tagManager: &CfTagManager{ - cfNameResolver: &mockCFClientWrapper{ + environment: "testing", + cfResourceGetter: &mockCFClientWrapper{ organizationName: "org-1", spaceName: "space-1", spaceGUID: "abc4", @@ -128,8 +173,10 @@ func TestGenerateTags(t *testing.T) { instanceGUID: "abc5", }, }, + expectedGetSpaceInstanceCallCount: 1, expectedTags: map[string]string{ "client": "Cloud Foundry", + "environment": "testing", "Service offering name": "abc1", "Service plan name": "abc2", "Organization GUID": "abc3", @@ -143,23 +190,93 @@ func TestGenerateTags(t *testing.T) { action: Create, serviceOfferingName: "abc1", servicePlanName: "abc2", - organizationGUID: "abc3", - spaceGUID: "abc4", - instanceGUID: "abc5", - environment: "", + resourceGUIDS: ResourceGUIDs{ + OrganizationGUID: "abc3", + SpaceGUID: "abc4", + InstanceGUID: "abc5", + }, tagManager: &CfTagManager{ broker: "AWS Broker", - cfNameResolver: &mockCFClientWrapper{ + cfResourceGetter: &mockCFClientWrapper{ + organizationName: "org-1", + spaceName: "space-1", + spaceGUID: "abc4", + organizationGUID: "abc3", + instanceGUID: "abc5", + }, + }, + expectedGetSpaceInstanceCallCount: 1, + expectedTags: map[string]string{ + "client": "Cloud Foundry", + "broker": "AWS Broker", + "Service offering name": "abc1", + "Service plan name": "abc2", + "Organization GUID": "abc3", + "Space GUID": "abc4", + "Instance GUID": "abc5", + "Organization name": "org-1", + "Space name": "space-1", + }, + }, + "get missing organization": { + action: Create, + serviceOfferingName: "abc1", + servicePlanName: "abc2", + resourceGUIDS: ResourceGUIDs{ + SpaceGUID: "abc4", + InstanceGUID: "abc5", + }, + getMissingResources: true, + tagManager: &CfTagManager{ + broker: "AWS Broker", + environment: "testing", + cfResourceGetter: &mockCFClientWrapper{ + organizationGUID: "abc3", organizationName: "org-1", spaceName: "space-1", + spaceGUID: "abc4", + instanceGUID: "abc5", + }, + }, + expectedGetSpaceInstanceCallCount: 1, + expectedTags: map[string]string{ + "client": "Cloud Foundry", + "broker": "AWS Broker", + "environment": "testing", + "Service offering name": "abc1", + "Service plan name": "abc2", + "Organization GUID": "abc3", + "Space GUID": "abc4", + "Instance GUID": "abc5", + "Organization name": "org-1", + "Space name": "space-1", + }, + }, + "get missing space and organization": { + action: Create, + serviceOfferingName: "abc1", + servicePlanName: "abc2", + resourceGUIDS: ResourceGUIDs{ + InstanceGUID: "abc5", + }, + getMissingResources: true, + tagManager: &CfTagManager{ + broker: "AWS Broker", + environment: "testing", + cfResourceGetter: &mockCFClientWrapper{ spaceGUID: "abc4", organizationGUID: "abc3", + organizationName: "org-1", + spaceName: "space-1", instanceGUID: "abc5", }, }, + expectedGetSpaceInstanceCallCount: 1, + expectedGetServiceInstanceCallCount: 1, expectedTags: map[string]string{ "client": "Cloud Foundry", "broker": "AWS Broker", + "environment": "testing", "Service offering name": "abc1", "Service plan name": "abc2", "Organization GUID": "abc3", @@ -169,18 +286,71 @@ func TestGenerateTags(t *testing.T) { "Space name": "space-1", }, }, + "no organization GUID, do not get missing resource": { + action: Create, + serviceOfferingName: "abc1", + servicePlanName: "abc2", + resourceGUIDS: ResourceGUIDs{ + SpaceGUID: "abc4", + InstanceGUID: "abc5", + }, + tagManager: &CfTagManager{ + broker: "AWS Broker", + environment: "testing", + cfResourceGetter: &mockCFClientWrapper{ + spaceGUID: "abc4", + spaceName: "space-1", + instanceGUID: "abc5", + }, + }, + expectedGetSpaceInstanceCallCount: 1, + expectedGetServiceInstanceCallCount: 0, + expectedTags: map[string]string{ + "client": "Cloud Foundry", + "broker": "AWS Broker", + "environment": "testing", + "Service offering name": "abc1", + "Service plan name": "abc2", + "Space GUID": "abc4", + "Instance GUID": "abc5", + "Space name": "space-1", + }, + }, + "no space or organization GUID, do not get missing resource": { + action: Create, + serviceOfferingName: "abc1", + servicePlanName: "abc2", + resourceGUIDS: ResourceGUIDs{ + InstanceGUID: "abc5", + }, + tagManager: &CfTagManager{ + broker: "AWS Broker", + environment: "testing", + cfResourceGetter: &mockCFClientWrapper{ + instanceGUID: "abc5", + }, + }, + expectedGetSpaceInstanceCallCount: 0, + expectedGetServiceInstanceCallCount: 0, + expectedTags: map[string]string{ + "client": "Cloud Foundry", + "broker": "AWS Broker", + "environment": "testing", + "Service offering name": "abc1", + "Service plan name": "abc2", + "Instance GUID": "abc5", + }, + }, } for name, test := range testCases { t.Run(name, func(t *testing.T) { tags, err := test.tagManager.GenerateTags( test.action, - test.environment, test.serviceOfferingName, test.servicePlanName, - test.organizationGUID, - test.spaceGUID, - test.instanceGUID, + test.resourceGUIDS, + test.getMissingResources, ) if err != nil { @@ -196,6 +366,16 @@ func TestGenerateTags(t *testing.T) { if !cmp.Equal(tags, test.expectedTags) { t.Errorf(cmp.Diff(tags, test.expectedTags)) } + + mockCfResourceGetter, ok := test.tagManager.cfResourceGetter.(*mockCFClientWrapper) + if ok { + if test.expectedGetServiceInstanceCallCount != mockCfResourceGetter.getServiceInstanceCallCount { + t.Fatalf("Expected %d calls to getServiceInstance, got %d", test.expectedGetServiceInstanceCallCount, mockCfResourceGetter.getServiceInstanceCallCount) + } + if test.expectedGetSpaceInstanceCallCount != mockCfResourceGetter.getSpaceInstanceCallCount { + t.Fatalf("Expected %d calls to getSpace, got %d", test.expectedGetSpaceInstanceCallCount, mockCfResourceGetter.getSpaceInstanceCallCount) + } + } }) } } @@ -205,22 +385,22 @@ func TestGenerateTagsHandleErrors(t *testing.T) { tagManager *CfTagManager expectedErr error }{ - "error getting organization name": { + "error getting organization": { tagManager: &CfTagManager{ - cfNameResolver: &mockCFClientWrapper{ - getOrganizationErr: errors.New("error getting organization name"), + cfResourceGetter: &mockCFClientWrapper{ + getOrganizationErr: errors.New("error getting organization"), }, }, - expectedErr: errors.New("error getting organization name"), + expectedErr: errors.New("error getting organization"), }, - "error getting space name": { + "error getting space": { tagManager: &CfTagManager{ broker: "AWS Broker", - cfNameResolver: &mockCFClientWrapper{ - getSpaceErr: errors.New("error getting space name"), + cfResourceGetter: &mockCFClientWrapper{ + getSpaceErr: errors.New("error getting space"), }, }, - expectedErr: errors.New("error getting space name"), + expectedErr: errors.New("error getting space"), }, } @@ -228,12 +408,14 @@ func TestGenerateTagsHandleErrors(t *testing.T) { t.Run(name, func(t *testing.T) { _, err := test.tagManager.GenerateTags( Create, - "testing", "abc1", "abc2", - "abc3", - "abc4", - "abc5", + ResourceGUIDs{ + OrganizationGUID: "org-1", + InstanceGUID: "instance-1", + SpaceGUID: "space-1", + }, + false, ) if err == nil || err.Error() != test.expectedErr.Error() { t.Fatalf("did not received expected err: %s, got: %s", test.expectedErr, err) @@ -241,3 +423,83 @@ func TestGenerateTagsHandleErrors(t *testing.T) { }) } } + +func TestGetSpaceGuid(t *testing.T) { + testCases := map[string]struct { + tagManager *CfTagManager + instanceGUID string + expectedGuid string + expectedErr error + }{ + "success": { + tagManager: &CfTagManager{ + cfResourceGetter: &mockCFClientWrapper{ + instanceGUID: "instance-1", + spaceGUID: "space-1", + }, + }, + instanceGUID: "instance-1", + expectedGuid: "space-1", + }, + "error": { + tagManager: &CfTagManager{ + cfResourceGetter: &mockCFClientWrapper{ + getServiceInstanceErr: errors.New("error getting service instance"), + }, + }, + expectedErr: errors.New("error getting service instance"), + }, + } + + for name, test := range testCases { + t.Run(name, func(t *testing.T) { + spaceGUID, err := test.tagManager.getSpaceGuid(test.instanceGUID) + if spaceGUID != test.expectedGuid { + t.Errorf("expected: %s, got: %s", test.expectedGuid, spaceGUID) + } + if (test.expectedErr != nil && err == nil) || + (err != nil && err.Error() != test.expectedErr.Error()) { + t.Errorf("expected error: %s, got: %s", test.expectedErr, err) + } + }) + } +} + +func TestGetOrganizationGuidFromSpace(t *testing.T) { + testCases := map[string]struct { + space *resource.Space + tagManager *CfTagManager + expectedGUID string + }{ + "success": { + tagManager: &CfTagManager{ + cfResourceGetter: &mockCFClientWrapper{}, + }, + space: &resource.Space{ + Name: "space-1", + Relationships: &resource.SpaceRelationships{ + Organization: &resource.ToOneRelationship{ + Data: &resource.Relationship{ + GUID: "org-guid-1", + }, + }, + }, + }, + expectedGUID: "org-guid-1", + }, + "nil space": { + tagManager: &CfTagManager{ + cfResourceGetter: &mockCFClientWrapper{}, + }, + }, + } + + for name, test := range testCases { + t.Run(name, func(t *testing.T) { + organizationGUID := test.tagManager.getOrganizationGuidFromSpace(test.space) + if organizationGUID != test.expectedGUID { + t.Errorf("expected GUID: %s, got: %s", test.expectedGUID, organizationGUID) + } + }) + } +}