Class: ForemanAnsible::VariablesImporter

Inherits:
Object
  • Object
show all
Includes:
ProxyAPI
Defined in:
app/services/foreman_ansible/variables_importer.rb

Overview

Methods to transform variable names coming from the proxy into Foreman AnsibleVariable objects

Constant Summary collapse

VARIABLE_TYPES =
{
  'TrueClass' => 'boolean',
  'FalseClass' => 'boolean',
  'Integer' => 'integer',
  'Fixnum' => 'integer',
  'Float' => 'real',
  'Array' => 'array',
  'Hash' => 'hash',
  'String' => 'string'
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(proxy = nil) ⇒ VariablesImporter

Returns a new instance of VariablesImporter.



20
21
22
# File 'app/services/foreman_ansible/variables_importer.rb', line 20

def initialize(proxy = nil)
  @ansible_proxy = proxy
end

Instance Method Details

#create_new_variables(variables) ⇒ Object



111
112
113
114
115
116
117
118
119
120
121
122
# File 'app/services/foreman_ansible/variables_importer.rb', line 111

def create_new_variables(variables)
  iterate_over_variables(variables) do |role, memo, attrs|
    variable = AnsibleVariable.new(
      JSON.parse(attrs)
    )
    # Make sure, newly created variables are not hidden
    variable.hidden_value = false
    variable.ansible_role = ::AnsibleRole.find_by(:name => role)
    variable.save
    memo << variable
  end
end

#delete_old_variables(variables) ⇒ Object



133
134
135
136
137
138
139
140
141
# File 'app/services/foreman_ansible/variables_importer.rb', line 133

def delete_old_variables(variables)
  iterate_over_variables(variables) do |_role, memo, attrs|
    variable = AnsibleVariable.find(
      JSON.parse(attrs)['id']
    )
    memo << variable.key
    variable.destroy
  end
end

#detect_changes(imported) ⇒ Object



92
93
94
95
96
97
98
99
100
101
# File 'app/services/foreman_ansible/variables_importer.rb', line 92

def detect_changes(imported)
  changes = {}.with_indifferent_access
  persisted, changes[:new] = imported.partition { |var| var.id.present? }
  changed, _old = persisted.partition(&:changed?)
  _overriden, changes[:update] = changed.partition(&:override?)
  changes[:obsolete] = AnsibleVariable.where.not(id: persisted.pluck(:id)).
                       where.not(imported: false)

  changes
end

#finish_import(new, obsolete, update) ⇒ Object



103
104
105
106
107
108
109
# File 'app/services/foreman_ansible/variables_importer.rb', line 103

def finish_import(new, obsolete, update)
  results = { :added => [], :obsolete => [], :updated => [] }
  results[:added] = create_new_variables(new) if new.present?
  results[:obsolete] = delete_old_variables(obsolete) if obsolete.present?
  results[:updated] = update_variables(update) if update.present?
  results
end

#get_variables_names(role_name) ⇒ Object



29
30
31
# File 'app/services/foreman_ansible/variables_importer.rb', line 29

def get_variables_names(role_name)
  remote_variables[role_name]
end

#import_new_role(role_name, new_roles) ⇒ Object



70
71
72
73
74
75
76
# File 'app/services/foreman_ansible/variables_importer.rb', line 70

def import_new_role(role_name, new_roles)
  role = AnsibleRole.find_by(:name => role_name)
  if role.blank? && new_roles.map(&:name).include?(role_name)
    role = new_roles.find { |r| r.name == role_name }
  end
  role
end

#import_variable_names(new_roles) ⇒ Object



24
25
26
27
# File 'app/services/foreman_ansible/variables_importer.rb', line 24

def import_variable_names(new_roles)
  return import_variables(remote_variables, new_roles) if @ansible_proxy
  import_variables(local_variables, new_roles)
end

#import_variables(role_variables, new_roles) ⇒ Object



33
34
35
36
37
38
39
40
# File 'app/services/foreman_ansible/variables_importer.rb', line 33

def import_variables(role_variables, new_roles)
  detect_changes(role_variables.map do |role_name, variables|
    next if variables.blank?
    role = import_new_role(role_name, new_roles)
    next if role.blank?
    initialize_variables(variables, role)
  end.select(&:present?).flatten.compact)
end

#import_variables_roles(roles) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'app/services/foreman_ansible/variables_importer.rb', line 42

def import_variables_roles(roles)
  if roles['new']
    imported_roles = roles['new'].keys
    variables_to_import = {}
    remote_variables.each do |role, variables|
      next unless imported_roles.include? role
      role_obj = AnsibleRole.find_by(:name => role)
      variables_to_import[role] = {}
      values = initialize_variables(variables, role_obj)
      values.each do |value|
        variables_to_import[role][value.key] = value.attributes.to_json
      end
    end
    create_new_variables(variables_to_import)
  end
  return if roles['old'].empty?
  variables_to_update = { 'new' => {}, 'obsolete' => {}, 'update' => {} }
  import_variable_names([]).each do |kind, variables|
    variables.each do |variable|
      next unless roles['old'].values.map { |role| role['id'] }.include?(variable.ansible_role_id)
      role_name = variable.ansible_role.name
      variables_to_update[kind][role_name] ||= {}
      variables_to_update[kind][role_name][variable.key] = variable.attributes.to_json
    end
  end
  finish_import(variables_to_update['new'], variables_to_update['obsolete'], variables_to_update['update'])
end

#initialize_variables(variables, role) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'app/services/foreman_ansible/variables_importer.rb', line 78

def initialize_variables(variables, role)
  variables.map do |variable_name, variable_default|
    variable = AnsibleVariable.find_or_initialize_by(
      :key => variable_name,
      :ansible_role_id => role.id
    )
    variable.assign_attributes(:hidden_value => false,
                               :default_value => variable_default,
                               :key_type => infer_key_type(variable_default))
    variable.imported = true if variable.new_record?
    variable.valid? ? variable : nil
  end
end

#update_variables(variables) ⇒ Object



124
125
126
127
128
129
130
131
# File 'app/services/foreman_ansible/variables_importer.rb', line 124

def update_variables(variables)
  iterate_over_variables(variables) do |_role, memo, attrs|
    attributes = JSON.parse(attrs)
    var = AnsibleVariable.find attributes['id']
    var.update(attributes)
    memo << var
  end
end