Skip to content

Commit

Permalink
Store next naming sequence in custom_attributes
Browse files Browse the repository at this point in the history
With this implemenation naming sequences are global through current region.
The binding can be changed to other models through NamingSequenceMixin.

https://bugzilla.redhat.com/show_bug.cgi?id=1173336
  • Loading branch information
bzwei committed Jan 29, 2015
1 parent f788619 commit d2689d3
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 20 deletions.
28 changes: 9 additions & 19 deletions vmdb/app/models/miq_provision/naming.rb
Expand Up @@ -3,6 +3,7 @@ module MiqProvision::Naming

NAME_VIA_AUTOMATE = true
NAME_SEQUENCE_REGEX = /\$n\{(\d+)\}/
SOURCE_IDENTIFIER = "provisioning" # a unique name for the source column in custom_attributes table

module ClassMethods
def get_next_vm_name(prov_obj, determine_index=true)
Expand Down Expand Up @@ -51,28 +52,20 @@ def get_vm_full_name(unresolved_vm_name, prov_obj, determine_index)
# if we are just building a sample of what the vm_name will look like use '#' inplace of actual number.
return "#{name[:prefix]}#{'#' * name[:index_length]}#{name[:suffix]}" if determine_index == false

# Determine starting index based on already assigned names in miq_provision table.
start_idx = 0
reg_val = Regexp.new("(#{name[:prefix]})(\\d{#{name[:index_length]}})(#{name[:suffix]})")

MiqProvision.find(:all).each do |p|
if p.options[:vm_target_name].to_s.strip =~ reg_val
name_prefix, name_idx, name_suffix = $1.to_s, $2.to_i, $3
# If the name prefix and suffix match record the highest index number
if name[:prefix].downcase == name_prefix.downcase && name[:suffix].to_s.downcase == name_suffix.to_s.downcase
start_idx = name_idx if name_idx > start_idx
end
index_length = name[:index_length]
loop do
next_number = MiqRegion.my_region.next_naming_sequence(unresolved_vm_name, SOURCE_IDENTIFIER)
idx_str = "%0#{index_length}d" % next_number
if idx_str.length > index_length
index_length += 1
unresolved_vm_name = "#{name[:prefix]}$n{#{index_length}}#{name[:suffix]}"
next
end
end
start_idx += 1

start_idx.upto(9999) do |x|
idx_str = format("%0#{name[:index_length]}d", x)
fullname = "#{name[:prefix]}#{idx_str}#{name[:suffix]}"
vm = check_vm_name_uniqueness(fullname, prov_obj)
return fullname if vm.nil?
end
return nil
end

def check_vm_name_uniqueness(fullname, prov_obj)
Expand All @@ -86,7 +79,4 @@ def check_vm_name_uniqueness(fullname, prov_obj)
def get_next_vm_name()
self.class.get_next_vm_name(self)
end



end
2 changes: 1 addition & 1 deletion vmdb/app/models/miq_region.rb
Expand Up @@ -19,7 +19,7 @@ class MiqRegion < ActiveRecord::Base
acts_as_miq_taggable
include ReportableMixin
include UuidMixin

include NamingSequenceMixin
include AggregationMixin
# Since we've overridden the implementation of methods from AggregationMixin,
# we must also override the :uses portion of the virtual columns.
Expand Down
17 changes: 17 additions & 0 deletions vmdb/app/models/mixins/naming_sequence_mixin.rb
@@ -0,0 +1,17 @@
module NamingSequenceMixin
extend ActiveSupport::Concern

included do
# these are possible naming sequences because there is no constraint to source column
has_many :naming_sequences, :as => :resource, :dependent => :destroy, :class_name => "CustomAttribute"
end

def next_naming_sequence(name, source)
lock do
record = naming_sequences.where(:name => name, :source => source).first_or_initialize
record.update_attributes!(:value => record.value.to_i + 1)

record.value
end
end
end
18 changes: 18 additions & 0 deletions vmdb/spec/models/miq_provision_spec.rb
Expand Up @@ -76,6 +76,24 @@
@vm_prov.get_option(:vm_target_hostname).should == name_002.gsub(/ +|_+/, "-")
end

context "when auto naming sequence exceeds the range" do
before do
region = MiqRegion.my_region
region.naming_sequences.create(:name => "#{@target_vm_name}$n{3}", :source => "provisioning", :value => 998)
region.naming_sequences.create(:name => "#{@target_vm_name}$n{4}", :source => "provisioning", :value => 10)
end

it "should advance to next range but based on the existing sequence number for the new range" do
@vm_prov.options[:number_of_vms] = 2
@vm_prov.after_request_task_create
@vm_prov.get_option(:vm_target_name).should == "#{@target_vm_name}999" # 3 digits

@vm_prov.options[:pass] = 2
@vm_prov.after_request_task_create
@vm_prov.get_option(:vm_target_name).should == "#{@target_vm_name}0011" # 4 digits
end
end

it "should create a hostname with a valid length based on the OS" do
# Hostname lengths by platform:
# Linux : 63
Expand Down
7 changes: 7 additions & 0 deletions vmdb/spec/models/miq_region_spec.rb
Expand Up @@ -27,6 +27,13 @@ def write_region(number)
MiqRegion.count.should == 1
end

it "should increment naming sequence number after each call" do
MiqRegion.my_region.next_naming_sequence("namingtest$n{3}", "naming").should == 1
MiqRegion.my_region.next_naming_sequence("namingtest$n{3}", "naming").should == 2
MiqRegion.my_region.next_naming_sequence("anothertest$n{3}", "naming").should == 1
MiqRegion.my_region.next_naming_sequence("anothertest$n{3}", "naming").should == 2
end

context "with cloud and infra EMSes" do

before :each do
Expand Down

0 comments on commit d2689d3

Please sign in to comment.