app/actions/labels_update.rb
require 'models/helpers/metadata_helpers'
module VCAP::CloudController
module LabelsUpdate
class << self
def update(resource, labels, label_klass, destroy_nil: true)
starting_label_count_for_resource = label_klass.where(resource_guid: resource.guid).count
labels ||= {}
labels.each do |label_key, label_value|
label_key = label_key.to_s
prefix, name = VCAP::CloudController::MetadataHelpers.extract_prefix(label_key)
if label_value.nil? && destroy_nil # Delete Label
label_klass.find(key_prefix: prefix.to_s, resource_guid: resource.guid, key_name: name)&.destroy
next
end
begin
tries ||= 2
label_klass.db.transaction(savepoint: true) do
label = label_klass.find(key_prefix: prefix.to_s, resource_guid: resource.guid, key_name: name)
if label.nil?
label_klass.create(resource_guid: resource.guid, key_name: name, key_prefix: prefix, value: label_value)
else
label.update(value: label_value)
end
end
rescue Sequel::UniqueConstraintViolation => e
if (tries -= 1).positive?
retry
else
v3_api_error!(:UniquenessError, e.message)
end
end
end
ending_label_count_for_resource = label_klass.where(resource_guid: resource.guid).count
validate_max_label_limit!(labels, starting_label_count_for_resource, ending_label_count_for_resource)
labels
end
private
def validate_max_label_limit!(labels, starting_label_count, ending_label_count)
return unless starting_label_count < ending_label_count && ending_label_count > max_labels_per_resource
raise CloudController::Errors::ApiError.new_from_details('LabelLimitExceeded', labels.size, max_labels_per_resource)
end
def max_labels_per_resource
VCAP::CloudController::Config.config.get(:max_labels_per_resource)
end
end
end
end