class OpenNebula::ServiceTemplate
Constants
- DOCUMENT_TYPE
- IMMUTABLE_ATTRS
-
List of attributes that can’t be changed in update operation
registration_time: this is internal info managed by OneFlow server
- ROLE_SCHEMA
- SCHEMA
Public Class Methods
Source
# File lib/opennebula/flow/service_template.rb, line 242 def self.init_default_vn_name_template(vn_name_template) # rubocop:disable Style/ClassVars @@vn_name_template = vn_name_template # rubocop:enable Style/ClassVars end
Source
# File lib/opennebula/flow/service_template.rb, line 461 def self.validate(template) validator = Validator::Validator.new( :default_values => true, :delete_extra_properties => false, :allow_extra_properties => true ) validator.validate!(template, SCHEMA) validate_values(template) end
Source
# File lib/opennebula/flow/service_template.rb, line 473 def self.validate_role(template) validator = Validator::Validator.new( :default_values => true, :delete_extra_properties => false, :allow_extra_properties => true ) validator.validate!(template, ROLE_SCHEMA) end
Source
# File lib/opennebula/flow/service_template.rb, line 510 def self.validate_values(template) parser = ElasticityGrammarParser.new roles = template['roles'] roles.each_with_index do |role, role_index| roles[role_index+1..-1].each do |other_role| if role['name'] == other_role['name'] raise Validator::ParseException, "Role name '#{role['name']}' is repeated" end end if !role['min_vms'].nil? && role['min_vms'].to_i > role['cardinality'].to_i raise Validator::ParseException, "Role '#{role['name']}' 'cardinality' must be " \ "greater than or equal to 'min_vms'" end if !role['max_vms'].nil? && role['max_vms'].to_i < role['cardinality'].to_i raise Validator::ParseException, "Role '#{role['name']}' 'cardinality' must be " \ "lower than or equal to 'max_vms'" end if ((role['elasticity_policies'] && !role['elasticity_policies'].empty?) || (role['scheduled_policies'] && !role['scheduled_policies'].empty?)) && (role['min_vms'].nil? || role['max_vms'].nil?) raise Validator::ParseException, "Role '#{role['name']}' with " \ " 'elasticity_policies' or " \ "'scheduled_policies'must define both 'min_vms'" \ " and 'max_vms'" end if role['elasticity_policies'] role['elasticity_policies'].each_with_index do |policy, index| exp = policy['expression'] if exp.empty? raise Validator::ParseException, "Role '#{role['name']}', elasticity policy " \ "##{index} 'expression' cannot be empty" end treetop = parser.parse(exp) next unless treetop.nil? raise Validator::ParseException, "Role '#{role['name']}', elasticity policy " \ "##{index} 'expression' parse error: " \ "#{parser.failure_reason}" end end next unless role['scheduled_policies'] role['scheduled_policies'].each_with_index do |policy, index| start_time = policy['start_time'] recurrence = policy['recurrence'] if !start_time.nil? if !policy['recurrence'].nil? raise Validator::ParseException, "Role '#{role['name']}', scheduled policy "\ "##{index} must define "\ "'start_time' or 'recurrence', but not both" end begin next if start_time.match(/^\d+$/) Time.parse(start_time) rescue ArgumentError raise Validator::ParseException, "Role '#{role['name']}', scheduled policy " \ "##{index} 'start_time' is not a valid " \ 'Time. Try with YYYY-MM-DD hh:mm:ss or ' \ '0YYY-MM-DDThh:mm:ssZ' end elsif !recurrence.nil? begin cron_parser = CronParser.new(recurrence) cron_parser.next rescue StandardError raise Validator::ParseException, "Role '#{role['name']}', scheduled policy " \ "##{index} 'recurrence' is not a valid " \ 'cron expression' end else raise Validator::ParseException, "Role '#{role['name']}', scheduled policy #" \ "#{index} needs to define either " \ "'start_time' or 'recurrence'" end end end end
Public Instance Methods
Source
# File lib/opennebula/flow/service_template.rb, line 250 def allocate(template_json) template = JSON.parse(template_json) ServiceTemplate.validate(template) template['registration_time'] = Integer(Time.now) super(template.to_json, template['name']) end
OpenNebula::DocumentJSON#allocate
Source
# File lib/opennebula/flow/service_template.rb, line 429 def clone(name) new_id = super doc = OpenNebula::ServiceTemplate.new_with_id(new_id, @client) rc = doc.info return rc if OpenNebula.is_error?(rc) body = JSON.parse(doc["TEMPLATE/#{TEMPLATE_TAG}"]) # add registration time, as the template is new body['registration_time'] = Integer(Time.now) # update the template with the new body DocumentJSON.instance_method(:update).bind(doc).call(body.to_json) # return the new document ID new_id end
Clones a service template
@param name [Stirng] New name
@return [Integer] New template ID
OpenNebula::Document#clone
Source
# File lib/opennebula/flow/service_template.rb, line 351 def clone_recursively(name, mode) recursive = mode == 'all' # clone the document to get new ID new_id = clone(name) return new_id if OpenNebula.is_error?(new_id) doc = OpenNebula::ServiceTemplate.new_with_id(new_id, @client) rc = doc.info return rc if OpenNebula.is_error?(rc) body = JSON.parse(doc["TEMPLATE/#{TEMPLATE_TAG}"]) cloned_templates = {} # iterate over roles to clone templates rc = body['roles'].each do |role| t_id = role['vm_template'] # if the template has already been cloned, just update the value if cloned_templates.keys.include?(t_id) role['vm_template'] = cloned_templates[t_id] next end template = OpenNebula::Template.new_with_id(t_id, @client) rc = template.info break rc if OpenNebula.is_error?(rc) # The maximum size is 128, so crop the template name if it # exceeds the limit new_name = "#{template.name}-#{name}" if new_name.size > 119 new_name = "#{template.name[0..(119 - name.size)]}-#{name}" end rc = template.clone(new_name, recursive) break rc if OpenNebula.is_error?(rc) # add new ID to the hash cloned_templates[t_id] = rc role['vm_template'] = rc end # if any error, rollback and delete the left templates if OpenNebula.is_error?(rc) cloned_templates.each do |_, value| template = OpenNebula::Template.new_with_id(value, @client) rc = template.info break rc if OpenNebula.is_error?(rc) rc = template.delete(recursive) break rc if OpenNebula.is_error?(rc) end return rc end # update the template with the new body doc.update(body.to_json) # return the new document ID new_id end
Clone service template and the VM templates asssociated to it
@param name [String] New template name @param mode [Symbol] Cloning mode (:all, :templates)
@return [Integer] New document ID
Source
# File lib/opennebula/flow/service_template.rb, line 266 def delete(type = nil) case type when 'all' recursive = true when 'templates' recursive = false end if type && type != 'none' rc = vm_template_ids return rc if OpenNebula.is_error?(rc) rc = rc.each do |t_id| t = OpenNebula::Template.new_with_id(t_id, @client) rc = t.info break rc if OpenNebula.is_error?(rc) rc = t.delete(recursive) break rc if OpenNebula.is_error?(rc) end end return rc if OpenNebula.is_error?(rc) super() end
Delete service template
@param type [String] Delete type
- none: just the service template - all: delete VM templates, images and service template - templates: delete VM templates and service template
OpenNebula::Document#delete
Source
# File lib/opennebula/flow/service_template.rb, line 483 def instantiate(merge_template) rc = nil if merge_template.nil? instantiate_template = JSON.parse(@body.to_json) else instantiate_template = JSON.parse(@body.to_json) .merge(merge_template) end begin ServiceTemplate.validate(instantiate_template) xml = OpenNebula::Service.build_xml service = OpenNebula::Service.new(xml, @client) rc = service.allocate(instantiate_template.to_json) rescue Validator::ParseException, JSON::ParserError => e return e end return rc if OpenNebula.is_error?(rc) service.info service end
Source
# File lib/opennebula/flow/service_template.rb, line 299 def template @body.to_json end
Retrieves the template
@return [String] json template
Source
# File lib/opennebula/flow/service_template.rb, line 311 def update(template_json, append = false) rc = info return rc if OpenNebula.is_error?(rc) template = JSON.parse(template_json) if append IMMUTABLE_ATTRS.each do |attr| unless template[attr].nil? return [false, "service_template/#{attr}"] end end else IMMUTABLE_ATTRS.each do |attr| # Allows updating the template without # specifying the immutable attributes if template[attr].nil? template[attr] = @body[attr] end next if template[attr] == @body[attr] return [false, "service_template/#{attr}"] end end template = @body.merge(template) if append ServiceTemplate.validate(template) super(template.to_json) end
Replaces the template contents
@param template_json [String] New template contents @param append [true, false] True to append new attributes instead of
replace the whole template
@return [nil, OpenNebula::Error
] nil in case of success, Error
otherwise
OpenNebula::DocumentJSON#update
Source
# File lib/opennebula/flow/service_template.rb, line 457 def update_raw(template_raw, append = false) super(template_raw, append) end
Replaces the raw template contents
@param template [String] New template contents, in the form KEY = VAL @param append [true, false] True to append new attributes instead of
replace the whole template
@return [nil, OpenNebula::Error
] nil in case of success, Error
otherwise
OpenNebula::DocumentJSON#update_raw
Source
# File lib/opennebula/flow/service_template.rb, line 619 def vm_template_ids rc = info return rc if OpenNebula.is_error?(rc) ret = [] @body['roles'].each do |role| t_id = Integer(role['vm_template']) ret << t_id unless ret.include?(t_id) end ret end
Retreives all associated VM templates IDs
@return [Array] VM templates IDs