11package serviceinstance
22
33import (
4+ "bytes"
45 "context"
6+ "crypto/sha256"
57 "encoding/json"
68 "time"
79
810 "github.com/cloudfoundry/go-cfclient/v3/client"
9- "github.com/nsf/jsondiff"
10- "github.com/pkg/errors"
11-
12- ctrl "sigs.k8s.io/controller-runtime"
13- k8s "sigs.k8s.io/controller-runtime/pkg/client"
14-
1511 xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
1612 "github.com/crossplane/crossplane-runtime/pkg/connection"
1713 "github.com/crossplane/crossplane-runtime/pkg/controller"
@@ -20,6 +16,10 @@ import (
2016 "github.com/crossplane/crossplane-runtime/pkg/ratelimiter"
2117 "github.com/crossplane/crossplane-runtime/pkg/reconciler/managed"
2218 "github.com/crossplane/crossplane-runtime/pkg/resource"
19+ "github.com/nsf/jsondiff"
20+ "github.com/pkg/errors"
21+ ctrl "sigs.k8s.io/controller-runtime"
22+ k8s "sigs.k8s.io/controller-runtime/pkg/client"
2323
2424 "github.com/SAP/crossplane-provider-cloudfoundry/apis/resources/v1alpha1"
2525 apisv1alpha1 "github.com/SAP/crossplane-provider-cloudfoundry/apis/v1alpha1"
@@ -175,21 +175,29 @@ func (c *external) Observe(ctx context.Context, mg resource.Managed) (managed.Ex
175175 case v1alpha1 .LastOperationSucceeded :
176176 // If the last operation succeeded, set the CR to available
177177 cr .SetConditions (xpv1 .Available ())
178+ var credentialsUpToDate bool
179+ desiredCredentials , err := extractCredentialSpec (ctx , c .kube , cr .Spec .ForProvider )
180+ if err != nil {
181+ return managed.ExternalObservation {}, errors .Wrap (err , errSecret )
182+ }
178183 // If parameter drift detection is enable, get actual credentials from the service instance
179184 if cr .Spec .EnableParameterDriftDetection {
180185 // Get the parameters of the service instance for drift detection
181186 cred , err := c .serviceinstance .GetServiceCredentials (ctx , r )
182187 if err != nil {
183188 return managed.ExternalObservation {ResourceExists : true }, errors .Wrap (err , errGetParameters )
184189 }
185- cr .Status .AtProvider .Credentials = cred
190+ cr .Status .AtProvider .Credentials = iSha256 (cred )
191+
192+ credentialsUpToDate = jsonContain (cred , desiredCredentials )
193+ } else {
194+ desiredHash := iSha256 (desiredCredentials )
195+
196+ credentialsUpToDate = bytes .Equal (desiredHash , cr .Status .AtProvider .Credentials )
186197 }
198+
187199 // Check if the credentials in the spec match the credentials in the external resource
188- desiredCredentials , err := extractCredentialSpec (ctx , c .kube , cr .Spec .ForProvider )
189- if err != nil {
190- return managed.ExternalObservation {}, errors .Wrap (err , errSecret )
191- }
192- upToDate := serviceinstance .IsUpToDate (& cr .Spec .ForProvider , r ) && jsonContain (cr .Status .AtProvider .Credentials , desiredCredentials )
200+ upToDate := credentialsUpToDate && serviceinstance .IsUpToDate (& cr .Spec .ForProvider , r )
193201
194202 return managed.ExternalObservation {ResourceExists : true , ResourceUpToDate : upToDate }, nil
195203 default :
@@ -236,8 +244,8 @@ func (c *external) Create(ctx context.Context, mg resource.Managed) (managed.Ext
236244 return managed.ExternalCreation {}, errors .Wrap (err , errUpdateCR )
237245 }
238246
239- // Save credentials in the status of the CR
240- cr .Status .AtProvider .Credentials = creds
247+ // Save hash value of credentials in the status of the CR
248+ cr .Status .AtProvider .Credentials = iSha256 ( creds )
241249 if err = c .kube .Status ().Update (ctx , cr ); err != nil {
242250 return managed.ExternalCreation {}, errors .Wrap (err , errUpdateCR )
243251 }
@@ -265,13 +273,8 @@ func (c *external) Update(ctx context.Context, mg resource.Managed) (managed.Ext
265273 return managed.ExternalUpdate {}, errors .Wrap (err , errUpdate )
266274 }
267275
268- if err := c .kube .Update (ctx , cr ); err != nil {
269- return managed.ExternalUpdate {}, errors .Wrap (err , errUpdateCR )
270- }
271-
272- // Save credentials in the status of the CR
273276 if creds != nil {
274- cr .Status .AtProvider .Credentials = creds
277+ cr .Status .AtProvider .Credentials = iSha256 ( creds )
275278 if err := c .kube .Status ().Update (ctx , cr ); err != nil {
276279 return managed.ExternalUpdate {}, errors .Wrap (err , errUpdateCR )
277280 }
@@ -403,3 +406,14 @@ func (s servicePlanInitializer) Initialize(ctx context.Context, mg resource.Mana
403406
404407 return s .kube .Update (ctx , cr )
405408}
409+
410+ // Small wrapper around sha256.Sum256()
411+ // info: if creds == nil, it will result in a hash value anyway (e3b0c44298...).
412+ // This should not be a security problem.
413+ func iSha256 (data []byte ) []byte {
414+ if len (data ) == 0 || string (data ) == "{}" {
415+ return nil
416+ }
417+ s := sha256 .Sum256 (data )
418+ return s [:]
419+ }
0 commit comments