Skip to content
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

service: --params flag retrieves service instance params #2141

Merged
merged 6 commits into from
Feb 19, 2021
Merged
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
@@ -0,0 +1,11 @@
package actionerror

// ServiceInstanceParamsFetchingNotSupportedError is returned when
// service instance is user provided or
// service instance retrievable is false for a managed service instance
type ServiceInstanceParamsFetchingNotSupportedError struct {
}

func (e ServiceInstanceParamsFetchingNotSupportedError) Error() string {
return "This service does not support fetching service instance parameters."
}
50 changes: 32 additions & 18 deletions actor/v7action/service_instance_details.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@ type SharedStatus struct {
UsageSummary []UsageSummaryWithSpaceAndOrg
}

type ServiceInstanceParameters struct {
Value types.JSONObject
MissingReason string
}
type ServiceInstanceParameters types.JSONObject

type ServiceInstanceUpgradeState int

Expand All @@ -57,7 +54,6 @@ type ServiceInstanceDetails struct {
ServiceOffering resources.ServiceOffering
ServicePlan resources.ServicePlan
ServiceBrokerName string
Parameters ServiceInstanceParameters
SharedStatus SharedStatus
UpgradeStatus ServiceInstanceUpgradeStatus
BoundApps []resources.ServiceCredentialBinding
Expand All @@ -71,10 +67,6 @@ func (actor Actor) GetServiceInstanceDetails(serviceInstanceName string, spaceGU
serviceInstanceDetails, warnings, err = actor.getServiceInstanceDetails(serviceInstanceName, spaceGUID)
return
},
func() (warnings ccv3.Warnings, err error) {
serviceInstanceDetails.Parameters, warnings = actor.getServiceInstanceParameters(serviceInstanceDetails.GUID)
return
},
func() (warnings ccv3.Warnings, err error) {
serviceInstanceDetails.SharedStatus, warnings, err = actor.getServiceInstanceSharedStatus(serviceInstanceDetails, spaceGUID)
return
Expand All @@ -97,6 +89,27 @@ func (actor Actor) GetServiceInstanceDetails(serviceInstanceName string, spaceGU
return serviceInstanceDetails, Warnings(warnings), nil
}

func (actor Actor) GetServiceInstanceParameters(serviceInstanceName string, spaceGUID string) (ServiceInstanceParameters, Warnings, error) {
var serviceInstance resources.ServiceInstance
var parameters ServiceInstanceParameters

warnings, err := railway.Sequentially(
func() (warnings ccv3.Warnings, err error) {
serviceInstance, _, warnings, err = actor.getServiceInstanceByNameAndSpace(serviceInstanceName, spaceGUID)
return
},
func() (warnings ccv3.Warnings, err error) {
parameters, warnings, err = actor.getServiceInstanceParameters(serviceInstance.GUID)
return
},
)
if err != nil {
return ServiceInstanceParameters{}, Warnings(warnings), err
}

return parameters, Warnings(warnings), nil
}

func (actor Actor) getServiceInstanceDetails(serviceInstanceName string, spaceGUID string) (ServiceInstanceDetails, ccv3.Warnings, error) {
query := []ccv3.Query{
{
Expand Down Expand Up @@ -142,17 +155,18 @@ func (actor Actor) getServiceInstanceDetails(serviceInstanceName string, spaceGU
return result, warnings, nil
}

func (actor Actor) getServiceInstanceParameters(serviceInstanceGUID string) (ServiceInstanceParameters, ccv3.Warnings) {
func (actor Actor) getServiceInstanceParameters(serviceInstanceGUID string) (ServiceInstanceParameters, ccv3.Warnings, error) {
params, warnings, err := actor.CloudControllerClient.GetServiceInstanceParameters(serviceInstanceGUID)
if err != nil {
if e, ok := err.(ccerror.V3UnexpectedResponseError); ok && len(e.Errors) > 0 {
return ServiceInstanceParameters{MissingReason: e.Errors[0].Detail}, warnings
} else {
return ServiceInstanceParameters{MissingReason: err.Error()}, warnings
}
}

return ServiceInstanceParameters{Value: params}, warnings
switch err := err.(type) {
blgm marked this conversation as resolved.
Show resolved Hide resolved
case nil:
return ServiceInstanceParameters(params), warnings, nil
case ccerror.ResourceNotFoundError,
ccerror.ServiceInstanceParametersFetchNotSupportedError:
return ServiceInstanceParameters{}, warnings, actionerror.ServiceInstanceParamsFetchingNotSupportedError{}
default:
return ServiceInstanceParameters{}, warnings, err
}
}

func (actor Actor) getServiceInstanceSharedStatus(serviceInstanceDetails ServiceInstanceDetails, targetedSpace string) (SharedStatus, ccv3.Warnings, error) {
Expand Down
223 changes: 162 additions & 61 deletions actor/v7action/service_instance_details_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,6 @@ var _ = Describe("Service Instance Details Action", func() {
nil,
)

fakeCloudControllerClient.GetServiceInstanceParametersReturns(
types.JSONObject{"foo": "bar"},
ccv3.Warnings{"some-parameters-warning"},
nil,
)

fakeCloudControllerClient.GetFeatureFlagReturns(
resources.FeatureFlag{Name: "service_instance_sharing", Enabled: true},
ccv3.Warnings{},
Expand Down Expand Up @@ -129,7 +123,6 @@ var _ = Describe("Service Instance Details Action", func() {
Expect(executionError).NotTo(HaveOccurred())
Expect(warnings).To(ConsistOf(
"some-service-instance-warning",
"some-parameters-warning",
"some-bindings-warning",
))
})
Expand All @@ -155,9 +148,6 @@ var _ = Describe("Service Instance Details Action", func() {
ServicePlan: resources.ServicePlan{Name: servicePlanName},
ServiceBrokerName: serviceBrokerName,
SharedStatus: SharedStatus{},
Parameters: ServiceInstanceParameters{
Value: types.JSONObject{"foo": "bar"},
},
BoundApps: []resources.ServiceCredentialBinding{
{
Type: resources.AppBinding,
Expand Down Expand Up @@ -263,53 +253,6 @@ var _ = Describe("Service Instance Details Action", func() {
})
})

Describe("getting the parameters", func() {
It("makes the correct call to get the parameters", func() {
Expect(fakeCloudControllerClient.GetServiceInstanceParametersCallCount()).To(Equal(1))
Expect(fakeCloudControllerClient.GetServiceInstanceParametersArgsForCall(0)).To(Equal(serviceInstanceGUID))
})

When("getting the parameters fails with an expected error", func() {
BeforeEach(func() {
fakeCloudControllerClient.GetServiceInstanceParametersReturns(
types.JSONObject{},
ccv3.Warnings{"some-parameters-warning"},
ccerror.V3UnexpectedResponseError{
V3ErrorResponse: ccerror.V3ErrorResponse{
Errors: []ccerror.V3Error{{
Code: 1234,
Detail: "cannot get parameters reason",
Title: "CF-SomeRandomError",
}},
},
},
)
})

It("does not return an error, but returns warnings and the reason", func() {
Expect(executionError).NotTo(HaveOccurred())
Expect(warnings).To(ContainElement("some-parameters-warning"))
Expect(serviceInstance.Parameters.MissingReason).To(Equal("cannot get parameters reason"))
})
})

When("getting the parameters fails with an another error", func() {
BeforeEach(func() {
fakeCloudControllerClient.GetServiceInstanceParametersReturns(
types.JSONObject{},
ccv3.Warnings{"some-parameters-warning"},
errors.New("not expected"),
)
})

It("does not return an error, but returns warnings and the reason", func() {
Expect(executionError).NotTo(HaveOccurred())
Expect(warnings).To(ContainElement("some-parameters-warning"))
Expect(serviceInstance.Parameters.MissingReason).To(Equal("not expected"))
})
})
})

Describe("sharing", func() {
When("targeting originating service instance space", func() {
When("the service instance has shared spaces", func() {
Expand Down Expand Up @@ -467,7 +410,7 @@ var _ = Describe("Service Instance Details Action", func() {
It("returns an empty service instance, warnings, and the error", func() {
Expect(serviceInstance).To(Equal(ServiceInstanceDetails{}))
Expect(executionError).To(MatchError("error getting feature flag"))
Expect(warnings).To(ConsistOf("some-service-instance-warning", "some-parameters-warning", warningMessage))
Expect(warnings).To(ConsistOf("some-service-instance-warning", warningMessage))
})
})

Expand All @@ -485,7 +428,7 @@ var _ = Describe("Service Instance Details Action", func() {
It("returns an empty service instance, warnings, and the error", func() {
Expect(serviceInstance).To(Equal(ServiceInstanceDetails{}))
Expect(executionError).To(MatchError("error getting offering"))
Expect(warnings).To(ConsistOf("some-service-instance-warning", "some-parameters-warning", warningMessage))
Expect(warnings).To(ConsistOf("some-service-instance-warning", warningMessage))
})
})

Expand Down Expand Up @@ -518,7 +461,7 @@ var _ = Describe("Service Instance Details Action", func() {
It("returns an empty service instance, warnings, and the error", func() {
Expect(serviceInstance).To(Equal(ServiceInstanceDetails{}))
Expect(executionError).To(MatchError("no service instance"))
Expect(warnings).To(ConsistOf("some-service-instance-warning", "some-parameters-warning", warningMessage))
Expect(warnings).To(ConsistOf("some-service-instance-warning", warningMessage))
})
})

Expand All @@ -542,7 +485,7 @@ var _ = Describe("Service Instance Details Action", func() {
It("returns an empty service instance, warnings, and the error", func() {
Expect(serviceInstance).To(Equal(ServiceInstanceDetails{}))
Expect(executionError).To(MatchError("no service instance"))
Expect(warnings).To(ConsistOf("some-service-instance-warning", "some-parameters-warning", warningMessage))
Expect(warnings).To(ConsistOf("some-service-instance-warning", warningMessage))
})
})

Expand Down Expand Up @@ -764,4 +707,162 @@ var _ = Describe("Service Instance Details Action", func() {
})
})
})

Describe("GetServiceInstanceParameters", func() {
const (
serviceInstanceName = "some-service-instance-name"
serviceInstanceGUID = "some-service-instance-guid"
spaceGUID = "some-source-space-guid"
)

var (
serviceInstanceParams ServiceInstanceParameters
warnings Warnings
executionError error
)

BeforeEach(func() {
fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceReturns(
resources.ServiceInstance{
Type: resources.ManagedServiceInstance,
Name: serviceInstanceName,
GUID: serviceInstanceGUID,
SpaceGUID: spaceGUID,
},
ccv3.IncludedResources{},
ccv3.Warnings{"some-service-instance-warning"},
nil,
)

fakeCloudControllerClient.GetServiceInstanceParametersReturns(
types.JSONObject{"foo": "bar"},
ccv3.Warnings{"some-parameters-warning"},
nil,
)

})

JustBeforeEach(func() {
serviceInstanceParams, warnings, executionError = actor.GetServiceInstanceParameters(serviceInstanceName, spaceGUID)
})

Describe("getting the service instance", func() {
It("makes the correct call to get the service instance", func() {
Expect(fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceCallCount()).To(Equal(1))
actualName, actualSpaceGUID, actualQuery := fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceArgsForCall(0)
Expect(actualName).To(Equal(serviceInstanceName))
Expect(actualSpaceGUID).To(Equal(spaceGUID))
Expect(actualQuery).To(BeNil())
})

When("the service instance cannot be found", func() {
BeforeEach(func() {
fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceReturns(
resources.ServiceInstance{},
ccv3.IncludedResources{},
ccv3.Warnings{},
ccerror.ServiceInstanceNotFoundError{Name: serviceInstanceName},
)
})

It("returns an error and warnings", func() {
Expect(executionError).To(MatchError(actionerror.ServiceInstanceNotFoundError{Name: serviceInstanceName}))
})

It("does not attempt any other requests", func() {
Expect(fakeCloudControllerClient.GetServiceInstanceParametersCallCount()).To(Equal(0))
Expect(fakeCloudControllerClient.GetFeatureFlagCallCount()).To(Equal(0))
Expect(fakeCloudControllerClient.GetServiceOfferingByGUIDCallCount()).To(Equal(0))
Expect(fakeCloudControllerClient.GetServiceInstanceSharedSpacesCallCount()).To(Equal(0))
Expect(fakeCloudControllerClient.GetServicePlanByGUIDCallCount()).To(Equal(0))
Expect(fakeCloudControllerClient.GetServiceCredentialBindingsCallCount()).To(Equal(0))
})
})

When("getting the service instance returns an error", func() {
BeforeEach(func() {
fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceReturns(
resources.ServiceInstance{},
ccv3.IncludedResources{},
ccv3.Warnings{"some-service-instance-warning"},
errors.New("no service instance"))
})

It("returns an error and warnings", func() {
Expect(executionError).To(MatchError("no service instance"))
Expect(warnings).To(ConsistOf("some-service-instance-warning"))
})

It("does not attempt any other requests", func() {
Expect(fakeCloudControllerClient.GetServiceInstanceParametersCallCount()).To(Equal(0))
Expect(fakeCloudControllerClient.GetFeatureFlagCallCount()).To(Equal(0))
Expect(fakeCloudControllerClient.GetServiceOfferingByGUIDCallCount()).To(Equal(0))
Expect(fakeCloudControllerClient.GetServiceInstanceSharedSpacesCallCount()).To(Equal(0))
Expect(fakeCloudControllerClient.GetServicePlanByGUIDCallCount()).To(Equal(0))
Expect(fakeCloudControllerClient.GetServiceCredentialBindingsCallCount()).To(Equal(0))
})
})
})

Describe("getting the parameters", func() {
It("makes the correct call to get the parameters", func() {
Expect(fakeCloudControllerClient.GetServiceInstanceParametersCallCount()).To(Equal(1))
Expect(fakeCloudControllerClient.GetServiceInstanceParametersArgsForCall(0)).To(Equal(serviceInstanceGUID))
})

It("returns parameters", func() {
Expect(serviceInstanceParams).To(Equal(
ServiceInstanceParameters(types.JSONObject{"foo": "bar"})))
})

When("getting the parameters fails with a ServiceInstanceParametersFetchNotSupportedError", func() {
BeforeEach(func() {
fakeCloudControllerClient.GetServiceInstanceParametersReturns(
types.JSONObject{},
ccv3.Warnings{"some-parameters-warning"},
ccerror.ServiceInstanceParametersFetchNotSupportedError{
Message: "This service does not support fetching service instance parameters.",
},
)
})

It("does not return an error, but returns warnings and the reason", func() {
Expect(executionError).To(MatchError(actionerror.ServiceInstanceParamsFetchingNotSupportedError{}))
Expect(warnings).To(ContainElement("some-parameters-warning"))
})
})

When("getting the parameters fails with a ResourceNotFoundError", func() {
BeforeEach(func() {
fakeCloudControllerClient.GetServiceInstanceParametersReturns(
types.JSONObject{},
ccv3.Warnings{"some-parameters-warning"},
ccerror.ResourceNotFoundError{
Message: "Service instance not found",
},
)
})

It("converts the error to fetching not supported", func() {
Expect(executionError).To(MatchError(actionerror.ServiceInstanceParamsFetchingNotSupportedError{}))
Expect(warnings).To(ContainElement("some-parameters-warning"))
})
})

When("getting the parameters fails with an another error", func() {
BeforeEach(func() {
fakeCloudControllerClient.GetServiceInstanceParametersReturns(
types.JSONObject{},
ccv3.Warnings{"some-parameters-warning"},
errors.New("not expected"),
)
})

It("does not return an error, but returns warnings and the reason", func() {
Expect(executionError).To(MatchError("not expected"))
Expect(warnings).To(ContainElement("some-parameters-warning"))
})
})
})
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package ccerror

// ServiceInstanceParametersFetchNotSupportedError is returned when
// the service instance is user-provided or
// service instance fetching is not supported for managed instances
type ServiceInstanceParametersFetchNotSupportedError struct {
Message string
}

func (e ServiceInstanceParametersFetchNotSupportedError) Error() string {
return e.Message
}
Loading