Skip to content

Commit c391d56

Browse files
pair-coding result implementing the decision matrix
External-name service plan return Set nil nil Unset nil error Set provided single Unset provided single
1 parent 526632f commit c391d56

1 file changed

Lines changed: 44 additions & 43 deletions

File tree

internal/controller/serviceinstance/controller.go

Lines changed: 44 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"bytes"
55
"context"
66
"crypto/sha256"
7-
"encoding/json"
87
"time"
98

109
"github.com/cloudfoundry/go-cfclient/v3/client"
@@ -16,6 +15,7 @@ import (
1615
"github.com/crossplane/crossplane-runtime/pkg/ratelimiter"
1716
"github.com/crossplane/crossplane-runtime/pkg/reconciler/managed"
1817
"github.com/crossplane/crossplane-runtime/pkg/resource"
18+
"github.com/google/uuid"
1919
"github.com/nsf/jsondiff"
2020
"github.com/pkg/errors"
2121
ctrl "sigs.k8s.io/controller-runtime"
@@ -31,19 +31,20 @@ import (
3131
)
3232

3333
const (
34-
resourceType = "ServiceInstance"
35-
externalSystem = "Cloud Foundry"
36-
errTrackPCUsage = "cannot track ProviderConfig usage"
37-
errNewClient = "cannot create a client for " + externalSystem
38-
errWrongCRType = "managed resource is not a " + resourceType
39-
errUpdateCR = "cannot update the managed resource"
40-
errGet = "cannot get " + resourceType + " in " + externalSystem
41-
errCreate = "cannot create " + resourceType + " in " + externalSystem
42-
errUpdate = "cannot update " + resourceType + " in " + externalSystem
43-
errDelete = "cannot delete " + resourceType + " in " + externalSystem
44-
errCleanFailed = "cannot delete failed service instance"
45-
errSecret = "cannot resolve secret reference"
46-
errGetParameters = "cannot get parameters of the service instance for drift detection. Please check this is supported or set enableParameterDriftDetection to false."
34+
resourceType = "ServiceInstance"
35+
externalSystem = "Cloud Foundry"
36+
errTrackPCUsage = "cannot track ProviderConfig usage"
37+
errNewClient = "cannot create a client for " + externalSystem
38+
errWrongCRType = "managed resource is not a " + resourceType
39+
errUpdateCR = "cannot update the managed resource"
40+
errGet = "cannot get " + resourceType + " in " + externalSystem
41+
errCreate = "cannot create " + resourceType + " in " + externalSystem
42+
errUpdate = "cannot update " + resourceType + " in " + externalSystem
43+
errDelete = "cannot delete " + resourceType + " in " + externalSystem
44+
errCleanFailed = "cannot delete failed service instance"
45+
errSecret = "cannot resolve secret reference"
46+
errGetParameters = "cannot get parameters of the service instance for drift detection. Please check this is supported or set enableParameterDriftDetection to false."
47+
errMissingServicePlan = "managed resource service instance requires a service plan"
4748
)
4849

4950
// Setup adds a controller that reconciles ServiceInstance CR.
@@ -374,41 +375,41 @@ func (s servicePlanInitializer) Initialize(ctx context.Context, mg resource.Mana
374375
return nil
375376
}
376377

377-
if cr.Spec.ForProvider.ServicePlan == nil {
378-
// fallback on crossplane.io/external-data annotation for backward compatibility
379-
sp := struct {
380-
ServicePlan *v1alpha1.ServicePlanParameters `json:"service_plan"`
381-
}{ServicePlan: &v1alpha1.ServicePlanParameters{}}
378+
if cr.Spec.ForProvider.ServicePlan != nil {
379+
// When ServicePlan is set we populate the service
380+
// plan ID based on the external resource GUID.
381+
cf, err := clients.ClientFnBuilder(ctx, s.kube)(mg)
382+
if err != nil {
383+
return errors.Wrapf(err, errNewClient)
384+
}
382385

383-
if data, ok := mg.GetAnnotations()["crossplane.io/external-data"]; ok {
384-
if err := json.Unmarshal([]byte(data), &sp); err == nil {
385-
cr.Spec.ForProvider.ServicePlan = sp.ServicePlan
386-
}
387-
} else {
388-
return nil
386+
opt := client.NewServicePlanListOptions()
387+
if cr.Spec.ForProvider.ServicePlan.Offering != nil {
388+
opt.ServiceOfferingNames.EqualTo(*cr.Spec.ForProvider.ServicePlan.Offering)
389+
}
390+
if cr.Spec.ForProvider.ServicePlan.Plan != nil {
391+
opt.Names.EqualTo(*cr.Spec.ForProvider.ServicePlan.Plan)
392+
}
393+
sp, err := cf.ServicePlans.Single(ctx, opt)
394+
if err != nil {
395+
return errors.Wrapf(err, "Cannot initialize service plan using serviceName/servicePlanName: %s:%s`", *cr.Spec.ForProvider.ServicePlan.Offering, *cr.Spec.ForProvider.ServicePlan.Plan)
389396
}
390-
}
391397

392-
// Lookup service plan during every reconciliation to detect an update service_plan of existing service.
393-
cf, err := clients.ClientFnBuilder(ctx, s.kube)(mg)
394-
if err != nil {
395-
return errors.Wrapf(err, errNewClient)
396-
}
397-
opt := client.NewServicePlanListOptions()
398-
if cr.Spec.ForProvider.ServicePlan.Offering != nil {
399-
opt.ServiceOfferingNames.EqualTo(*cr.Spec.ForProvider.ServicePlan.Offering)
400-
}
401-
if cr.Spec.ForProvider.ServicePlan.Plan != nil {
402-
opt.Names.EqualTo(*cr.Spec.ForProvider.ServicePlan.Plan)
403-
}
404-
sp, err := cf.ServicePlans.Single(ctx, opt)
405-
if err != nil {
406-
return errors.Wrapf(err, "Cannot initialize service plan using serviceName/servicePlanName: %s:%s`", *cr.Spec.ForProvider.ServicePlan.Offering, *cr.Spec.ForProvider.ServicePlan.Plan)
398+
cr.Spec.ForProvider.ServicePlan.ID = &sp.GUID
399+
400+
return s.kube.Update(ctx, cr)
407401
}
408402

409-
cr.Spec.ForProvider.ServicePlan.ID = &sp.GUID
403+
// Service plan is not set
404+
guid := meta.GetExternalName(cr)
405+
406+
if _, err := uuid.Parse(guid); err == nil {
407+
// We have a valid external-name annotation
408+
return nil
409+
}
410410

411-
return s.kube.Update(ctx, cr)
411+
// No valid external-name annotation
412+
return errors.New(errMissingServicePlan)
412413
}
413414

414415
// Small wrapper around sha256.Sum256()

0 commit comments

Comments
 (0)