Class: JobTemplate

Inherits:
Template
  • Object
show all
Extended by:
FriendlyId
Includes:
Authorizable, ForemanRemoteExecution::Exportable, Parameterizable::ByIdName, Taxonomix
Defined in:
app/models/job_template.rb

Defined Under Namespace

Classes: NonUniqueInputsError

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ForemanRemoteExecution::Exportable

#export_attr, #export_iterable, #to_export

Class Method Details

.base_classObject

we have to override the base_class because polymorphic associations does not detect it correctly, more details at apidock.com/rails/ActiveRecord/Associations/ClassMethods/has_many#1010-Polymorphic-has-many-within-inherited-class-gotcha



61
62
63
# File 'app/models/job_template.rb', line 61

def self.base_class
  self
end

.import(contents, options = {}) ⇒ Object

Import a template from ERB, with YAML metadata in the first comment. It will overwrite (sync) an existing template if options is true.



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'app/models/job_template.rb', line 68

def self.import(contents, options = {})
  transaction do
     = (contents)
    return if .blank? || .delete('kind') != 'job_template'

    # Don't look for existing if we should always create a new template
    existing = self.find_by_name(['name']) unless options.delete(:build_new)
    # Don't update if the template already exists, unless we're told to
    return if !options.delete(:update) && existing

    template = existing || self.new
    template.sync_inputs(.delete('template_inputs'))
    template.sync_foreign_input_sets(.delete('foreign_input_sets'))
    template.sync_feature(.delete('feature'))
    template.assign_attributes(.merge(:template => contents.gsub(/<%\#.+?.-?%>\n?/m, '').strip).merge(options))
    template.assign_taxonomies if template.new_record?

    template
  end
end

.import!(template, options = {}) ⇒ Object



89
90
91
92
93
# File 'app/models/job_template.rb', line 89

def self.import!(template, options = {})
  template = import(template, options)
  template.save! if template
  template
end

.parse_metadata(template) ⇒ Object



203
204
205
206
# File 'app/models/job_template.rb', line 203

def self.(template)
  match = template.match(/<%\#(.+?).-?%>/m)
  match.nil? ? {} : YAML.load(match[1])
end

Instance Method Details

#assign_taxonomiesObject



122
123
124
125
126
127
# File 'app/models/job_template.rb', line 122

def assign_taxonomies
  if default
    organizations << Organization.all if SETTINGS[:organizations_enabled]
    locations << Location.all if SETTINGS[:locations_enabled]
  end
end

#dupObject



114
115
116
117
118
119
120
# File 'app/models/job_template.rb', line 114

def dup
  dup = super
  self.template_inputs.each do |input|
    dup.template_inputs.build input.attributes.except('template_id', 'id', 'created_at', 'updated_at')
  end
  dup
end

#effective_userObject



133
134
135
# File 'app/models/job_template.rb', line 133

def effective_user
  super || (build_effective_user.tap(&:set_defaults))
end

#filenameObject

‘Package Action - SSH Default’ => ‘package_action_ssh_default.erb’



100
101
102
# File 'app/models/job_template.rb', line 100

def filename
  name.downcase.delete('-').gsub(/\s+/, '_') + '.erb'
end

#generate_description_formatObject



137
138
139
140
141
142
143
144
145
146
147
148
# File 'app/models/job_template.rb', line 137

def generate_description_format
  if description_format.blank?
    generated_description = '%{job_category}'
    unless template_inputs_with_foreign.empty?
      inputs = template_inputs_with_foreign.map(&:name).map { |name| %{#{name}="%{#{name}}"} }.join(' ')
      generated_description << " with inputs #{inputs}"
    end
    generated_description
  else
    description_format
  end
end

#metadataObject



95
96
97
# File 'app/models/job_template.rb', line 95

def 
  "<%#\n#{to_export(false).to_yaml.sub(/\A---$/, '').strip}\n%>\n\n"
end

#providerObject



129
130
131
# File 'app/models/job_template.rb', line 129

def provider
  RemoteExecutionProvider.provider_for(provider_type)
end

#sync_feature(feature_name) ⇒ Object



197
198
199
200
201
# File 'app/models/job_template.rb', line 197

def sync_feature(feature_name)
  if feature_name && (feature = RemoteExecutionFeature.feature(feature_name)) && feature.job_template.blank?
    self.remote_execution_features << feature
  end
end

#sync_foreign_input_sets(input_sets) ⇒ Object



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'app/models/job_template.rb', line 175

def sync_foreign_input_sets(input_sets)
  input_sets ||= []

  input_sets = input_sets.inject({}) do |h, input_set|
    target_template = JobTemplate.find_by!(:name => input_set.delete('template'))
    input_set['target_template_id'] = target_template.id
    h.update(target_template.id => input_set)
  end

  # Sync existing input sets
  foreign_input_sets.each do |existing_input_set|
    if input_sets.include?(existing_input_set.target_template_id)
      existing_input_set.assign_attributes(input_sets.delete(existing_input_set.target_template_id))
    else
      existing_input_set.mark_for_destruction
    end
  end

  # Create new input_sets
  input_sets.values.each { |input_set| self.foreign_input_sets.build(input_set) }
end

#sync_inputs(inputs) ⇒ Object



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'app/models/job_template.rb', line 157

def sync_inputs(inputs)
  inputs ||= []
  # Build a hash where keys are input names
  inputs = inputs.inject({}) { |h, input| h.update(input['name'] => input) }

  # Sync existing inputs
  template_inputs.each do |existing_input|
    if inputs.include?(existing_input.name)
      existing_input.assign_attributes(inputs.delete(existing_input.name))
    else
      existing_input.mark_for_destruction
    end
  end

  # Create new inputs
  inputs.values.each { |new_input| template_inputs.build(new_input) }
end

#to_erbObject



104
105
106
# File 'app/models/job_template.rb', line 104

def to_erb
   + template
end

#used_taxonomy_ids(type) ⇒ Object

Override method in Taxonomix as Template is not used attached to a Host, and matching a Host does not prevent removing a template from its taxonomy.



110
111
112
# File 'app/models/job_template.rb', line 110

def used_taxonomy_ids(type)
  []
end

#validate_unique_inputs!Object



150
151
152
153
154
155
# File 'app/models/job_template.rb', line 150

def validate_unique_inputs!
  duplicated_inputs = template_inputs_with_foreign.group_by(&:name).values.select { |values| values.size > 1 }.map(&:first)
  unless duplicated_inputs.empty?
    raise NonUniqueInputsError.new(N_('Duplicated inputs detected: %{duplicated_inputs}'), :duplicated_inputs => duplicated_inputs.map(&:name))
  end
end