Skip to content

Commit

Permalink
Merge pull request #13713 from zeari/master
Browse files Browse the repository at this point in the history
Escape label names and values when put into tags
  • Loading branch information
gtanzillo authored Mar 10, 2017
2 parents 8bb9133 + 20f0edd commit 151e5c4
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 4 deletions.
10 changes: 9 additions & 1 deletion app/models/metric/chargeback_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,15 @@ def tag_list_with_prefix
if resource.kind_of?(Container)
state = resource.vim_performance_state_for_ts(timestamp.to_s)
image_tag_name = "#{state.image_tag_names}|" if state
labels = resource.try(:container_image).try(:docker_labels).try(:collect) { |l| "container_image/label/managed/#{l.name}/#{l.value}" }
labels = resource.try(:container_image).try(:docker_labels).try(:collect_concat) do |l|
escaped_name = AssignmentMixin.escape(l.name)
escaped_value = AssignmentMixin.escape(l.value)
[
# The assignments in tags can appear the old way as they are, or escaped
"container_image/label/managed/#{l.name}/#{l.value}",
"container_image/label/managed/#{escaped_name}/#{escaped_value}"
]
end
end

"#{image_tag_name}#{tag_names}".split("|").reject(&:empty?).map { |x| "#{tag_prefix}#{x}" } + (labels || [])
Expand Down
32 changes: 30 additions & 2 deletions app/models/mixins/assignment_mixin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

module AssignmentMixin
extend ActiveSupport::Concern
ESCAPED_PREFIX = "escaped".freeze

included do #:nodoc:
acts_as_miq_taggable

Expand Down Expand Up @@ -58,7 +60,9 @@ def assign_to_labels(objects, klass)
next
end
end
tag = "#{klass.underscore}/label/managed/#{obj.name}/#{obj.value}"
name = AssignmentMixin.escape(obj.name)
value = AssignmentMixin.escape(obj.value)
tag = "#{klass.underscore}/label/managed/#{name}/#{value}"
tag_add(tag, :ns => namespace)
end
reload
Expand All @@ -81,14 +85,38 @@ def get_assigned_tos
tag = Tag.find_by(:name => "/" + parts.join("/"))
result[:tags] << [Classification.find_by(:tag_id => tag.id), klass] unless tag.nil?
when :label
label = CustomAttribute.find_by(:name => parts[1], :value => parts[2])
label = if AssignmentMixin.escaped?(parts[1])
name = AssignmentMixin.unescape(parts[1])
value = AssignmentMixin.unescape(parts[2])
CustomAttribute.find_by(:name => name, :value => value)
else
CustomAttribute.find_by(:name => parts[1], :value => parts[2])
end
result[:labels] << [label, klass] unless label.nil?
end
end

result
end

# make strings with special characters like '/' safe to put in tags(assignments) by escaping them
def self.escape(string)
@parser ||= URI::RFC2396_Parser.new
escaped_string = @parser.escape(string, /[^A-Za-z0-9]/)
"#{ESCAPED_PREFIX}:{#{escaped_string}}" # '/escape/string' --> 'escaped:{%2Fescape%2Fstring}'
end

# return the escaped string back into a normal string
def self.unescape(escaped_string)
_log.info("not an escaped string: #{escaped_string}") unless escaped?(escaped_string)
@parser ||= URI::RFC2396_Parser.new
@parser.unescape(escaped_string.slice(ESCAPED_PREFIX.length + 2..-2)) # 'escaped:{%2Fescape%2Fstring}' --> '/escape/string'
end

def self.escaped?(string)
string.starts_with?("#{ESCAPED_PREFIX}:{") && string.ends_with?("}")
end

def remove_all_assigned_tos(cat = nil)
# Optional cat arg can be as much of the tail portion (after /miq_alert/assigned_to/) as desired
# Example: If Tags = "/miq_alert/assigned_to/host/tag/managed/environment/prod" and
Expand Down
2 changes: 1 addition & 1 deletion spec/models/chargeback_container_image_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
EvmSpecHelper.create_guid_miq_server_zone
@node = FactoryGirl.create(:container_node, :name => "node")
@image = FactoryGirl.create(:container_image, :ext_management_system => ems)
@label = FactoryGirl.build(:custom_attribute, :name => "version_label-1", :value => "1.0.0-rc_2", :section => 'docker_labels')
@label = FactoryGirl.build(:custom_attribute, :name => "version/1.2/_label-1", :value => "test/1.0.0 rc_2", :section => 'docker_labels')
@project = FactoryGirl.create(:container_project, :name => "my project", :ext_management_system => ems)
@group = FactoryGirl.create(:container_group, :ext_management_system => ems, :container_project => @project,
:container_node => @node)
Expand Down

0 comments on commit 151e5c4

Please sign in to comment.