func()

in pkg/controller/direct/bigquerydataset/dataset_controller.go [193:290]


func (a *Adapter) Update(ctx context.Context, updateOp *directbase.UpdateOperation) error {
	u := updateOp.GetUnstructured()

	log := klog.FromContext(ctx).WithName(ctrlName)
	log.V(2).Info("updating Dataset", "name", a.id.String())
	mapCtx := &direct.MapContext{}

	// Convert KRM object to proto message
	desiredKRM := a.desired.DeepCopy()
	desired := BigQueryDatasetSpec_ToProto(mapCtx, &desiredKRM.Spec)
	if mapCtx.Err() != nil {
		return mapCtx.Err()
	}

	resource := cloneBigQueryDatasetMetadate(a.actual)
	// Check for immutable fields
	if desiredKRM.Spec.Location != nil && !reflect.DeepEqual(desired.Location, resource.Location) {
		return fmt.Errorf("BigQueryDataset %s/%s location cannot be changed, actual: %s, desired: %s", u.GetNamespace(), u.GetName(), resource.Location, desired.Location)
	}
	// Find diff
	updateMask := &fieldmaskpb.FieldMask{}
	if desired.Description != "" && !reflect.DeepEqual(desired.Description, resource.Description) {
		resource.Description = desired.Description
		updateMask.Paths = append(updateMask.Paths, "description")
	}
	if desired.Name != "" && !reflect.DeepEqual(desired.Name, resource.Name) {
		resource.Name = desired.Name
		updateMask.Paths = append(updateMask.Paths, "friendly_name")
	}
	if desired.DefaultPartitionExpiration != 0 && !reflect.DeepEqual(desired.DefaultPartitionExpiration, resource.DefaultPartitionExpiration) {
		resource.DefaultPartitionExpiration = desired.DefaultPartitionExpiration
		updateMask.Paths = append(updateMask.Paths, "default_partition_expiration")
	}
	if desired.DefaultTableExpiration != 0 && !reflect.DeepEqual(desired.DefaultTableExpiration, resource.DefaultTableExpiration) {
		resource.DefaultTableExpiration = desired.DefaultTableExpiration
		updateMask.Paths = append(updateMask.Paths, "default_table_expiration")
	}
	if desired.DefaultCollation != "" && !reflect.DeepEqual(desired.DefaultCollation, resource.DefaultCollation) {
		resource.DefaultCollation = desired.DefaultCollation
		updateMask.Paths = append(updateMask.Paths, "default_collation")
	}
	if desired.DefaultEncryptionConfig != nil && resource.DefaultEncryptionConfig != nil && !reflect.DeepEqual(desired.DefaultEncryptionConfig, resource.DefaultEncryptionConfig) {
		// Resolve KMS key reference
		if a.desired.Spec.DefaultEncryptionConfiguration != nil {
			kmsRef, err := refs.ResolveKMSCryptoKeyRef(ctx, a.reader, a.desired, a.desired.Spec.DefaultEncryptionConfiguration.KmsKeyRef)
			if err != nil {
				return err
			}
			desired.DefaultEncryptionConfig.KMSKeyName = kmsRef.External
		}
		resource.DefaultEncryptionConfig.KMSKeyName = desired.DefaultEncryptionConfig.KMSKeyName
		updateMask.Paths = append(updateMask.Paths, "default_encryption_configuration")
	}
	if desiredKRM.Spec.IsCaseInsensitive != nil && !reflect.DeepEqual(desired.IsCaseInsensitive, resource.IsCaseInsensitive) {
		resource.IsCaseInsensitive = desired.IsCaseInsensitive
		updateMask.Paths = append(updateMask.Paths, "is_case_sensitive")
	}
	if desired.StorageBillingModel != "" && !reflect.DeepEqual(desired.StorageBillingModel, resource.StorageBillingModel) {
		resource.StorageBillingModel = desired.StorageBillingModel
		updateMask.Paths = append(updateMask.Paths, "storage_billing_model")
	}
	// If we do not set a value, the GCP service defaults to 168
	// If the existing value is 168, it means that we did not set this field at creation and it defaults to 168.
	// So if the desired value is 0, it means that we do not intend to update this field.
	if desired.MaxTimeTravel != 0 && !reflect.DeepEqual(desired.MaxTimeTravel, resource.MaxTimeTravel) && (resource.MaxTimeTravel != 168 && desired.MaxTimeTravel != 0) {
		resource.MaxTimeTravel = desired.MaxTimeTravel
		updateMask.Paths = append(updateMask.Paths, "max_time_travel")
	}
	if desired.Access != nil && resource.Access != nil && len(desired.Access) > 0 && !reflect.DeepEqual(desired.Access, resource.Access) {
		for _, access := range desired.Access {
			resource.Access = append(resource.Access, access)
		}
	}
	if len(updateMask.Paths) == 0 {
		return nil
	}

	// Compute the dataset metadate for update request
	datasetMetadataToUpdate := BigQueryDataset_ToMetadataToUpdate(mapCtx, resource, updateMask.Paths)
	for k, v := range a.desired.GetObjectMeta().GetLabels() {
		datasetMetadataToUpdate.SetLabel(k, v)
	}
	datasetMetadataToUpdate.SetLabel("managed-by-cnrm", "true")
	// Call update
	dsHandler := a.gcpService.DatasetInProject(a.id.Parent().ProjectID, a.id.ID())
	updated, err := dsHandler.Update(ctx, *datasetMetadataToUpdate, "")
	if err != nil {
		return fmt.Errorf("updating Dataset %s: %w", a.id.String(), err)
	}
	log.V(2).Info("successfully updated Dataset", "name", a.id.String())

	status := &krm.BigQueryDatasetStatus{}
	status = BigQueryDatasetStatus_FromProto(mapCtx, updated)
	if mapCtx.Err() != nil {
		return mapCtx.Err()
	}
	return updateOp.UpdateStatus(ctx, status, nil)
}