foreman_templates 5.0.1 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3889bfa2270632f8e0bfacc4a35a1a85c3eca1e6
4
- data.tar.gz: 797795544b68cbb4b2d408e8293e6689d1e3ff02
3
+ metadata.gz: 756a604ec2486b327c246ae19a1c2b153c4217b7
4
+ data.tar.gz: 563b26321d12a2fad2b8d3f8f9202bcba689cf70
5
5
  SHA512:
6
- metadata.gz: da4517d69b72c25c3065db6f0afba3621b6165c9c7a8e317a52e0a4c24a81b369fac520cc50ea102ea7accc8b9934452ef38b4a6e270e15d28c2a606e4105688
7
- data.tar.gz: ae821ae58dedaaa29a83e41924b1ac30383c0d40e827c6d039397ac7bfd95f7923c94d418fcc1f89bcc59a020ae3b58b385db90bcb71353420384e8b31d4ba01
6
+ metadata.gz: 5cc02e60ced60af1126efed7dda4c89c167a8a59f8a009c3eb9c2fcd855d4f4c61cc4083d15c41993e4583f5fe367b5114c3fa38d9f44a388d8422385ca9f37b
7
+ data.tar.gz: 8638ebcf4335c45bf137ece2bd534a94e3f7dbc30040e4d5ee7c9c020c1258a159d10a769acc89a19c99174fe13d479d450181bf0d16cdad168fc07f6b280fd4
data/README.md CHANGED
@@ -26,7 +26,7 @@ These can be overriden for each import by passing options directly to a Rake tas
26
26
 
27
27
  ## Usage
28
28
 
29
- ### Import
29
+ ### Import via Rake task
30
30
 
31
31
  The plugin provides a Rake task to import the templates. To use it, simply do
32
32
 
@@ -49,6 +49,7 @@ template will be automatically associated with the OS
49
49
  * dirname => The directory within the git tree containing the templates [/]
50
50
  * filter => Import names matching this regex (case-insensitive; snippets are not filtered)
51
51
  * associate => Associate to OS, "always", when "new" or "never" [new]
52
+ * lock => Lock imported templates [false]
52
53
 
53
54
  The `branch` default will use *develop* if you're on Foreman-nightly; or the
54
55
  matching *1.X-stable* branch for your version of Foreman (if it exists); or
@@ -102,6 +103,15 @@ Purge all templates that do not begin with 'Community '
102
103
 
103
104
  foreman-rake templates:purge negate=true
104
105
 
106
+ ### Import and Export via API
107
+
108
+ There is an API (`/template/import/`) to initiate import from external
109
+ repository. The API uses Foreman's authorization and authentication
110
+ mechanisms. There is also an export action available.
111
+
112
+ Unfortunately, there is no CLI support yet. For examples about how to
113
+ use the API, [visit our documentation](https://theforeman.org/plugins/foreman_templates/5.0/index.html#5.API).
114
+
105
115
  ## Integration with other Foreman Plugins
106
116
 
107
117
  `templates` will start processing a template by looking for a metadata entry of
@@ -135,10 +145,6 @@ get written to a file in `/tmp`.
135
145
  * `:old` and `:new` (in which case this plugin will calculate the diff)
136
146
  * :result` (text, may be nil).
137
147
 
138
- ## TODO
139
-
140
- * Add a button to the UI with Deface to run the rake task
141
-
142
148
  ## Copyright
143
149
 
144
150
  Copyright (c) 2013 Greg Sutcliffe
data/Rakefile CHANGED
File without changes
@@ -1,54 +1,37 @@
1
1
  module Api
2
2
  module V2
3
3
  class TemplateController < ::Api::V2::BaseController
4
- api :POST, "/template/import/", N_("Initiate Import")
5
- param :verbose, :bool, :required => false, :desc => N_("Set verbosity of import")
6
- param :repo, String, :required => false, :desc => N_("Override the default repo from settings.")
7
- param :branch, String, :required => false, :desc => N_("Branch in Git repo.")
4
+ include ::Foreman::Controller::Parameters::TemplateParams
5
+
6
+ def_param_group :foreman_template_sync_params do
7
+ param :branch, String, :required => false, :desc => N_("Branch in Git repo.")
8
+ param :repo, String, :required => false, :desc => N_("Override the default repo from settings.")
9
+ param :filter, String, :required => false, :desc => N_("Export templates with names matching this regex (case-insensitive; snippets are not filtered).")
10
+ param :negate, :bool, :required => false, :desc => N_("Negate the prefix (for purging).")
11
+ param :dirname, String, :required => false, :desc => N_("The directory within Git repo containing the templates")
12
+ param :verbose, :bool, :required => false, :desc => N_("Set verbosity of import")
13
+ end
14
+
15
+ api :POST, "/templates/import/", N_("Initiate Import")
8
16
  param :prefix, String, :required => false, :desc => N_("The string all imported templates should begin with.")
9
- param :dirname, String, :required => false, :desc => N_("The directory within the git tree containing the templates.")
10
- param :filter, String, :required => false, :desc => N_("Import templates with names matching this regex (case-insensitive; snippets are not filtered).")
11
- param :negate, :bool, :required => false, :desc => N_("Negate the prefix (for purging).")
12
17
  param :associate, Setting::TemplateSync.associate_types.keys, :required => false, :desc => N_("Associate to OS's, Locations & Organizations. Options are: always, new or never.")
13
18
  param :force, :bool, :required => false, :desc => N_("Update templates that are locked")
14
-
19
+ param :lock, :bool, :required => false, :desc => N_("Lock imported templates")
20
+ param_group :foreman_template_sync_params
15
21
  def import
16
- results = ForemanTemplates::TemplateImporter.new({
17
- verbose: params['verbose'],
18
- repo: params['repo'],
19
- branch: params['branch'],
20
- prefix: params['prefix'],
21
- dirname: params['dirname'],
22
- filter: params['filter'],
23
- associate: params['associate'],
24
- negate: params['negate'],
25
- force: params['force']
26
- }).import!
22
+ results = ForemanTemplates::TemplateImporter.new(template_import_params).import!
27
23
  render :json => { :message => results }
28
24
  end
29
25
 
30
- api :POST, "/template/export", N_("Initiate Export")
31
- param :verbose, :bool, :required => false, :desc => N_("Set verbosity of export")
32
- param :repo, String, :required => false, :desc => N_("Override the default repo from settings")
33
- param :branch, String, :required => false, :desc => N_("Branch in Git repo.")
34
- param :filter, String, :required => false, :desc => N_("Export templates with names matching this regex (case-insensitive; snippets are not filtered).")
35
- param :negate, :bool, :required => false, :desc => N_("Negate the prefix (for purging).")
26
+ api :POST, "/templates/export", N_("Initiate Export")
36
27
  param :metadata_export_mode, Setting::TemplateSync.metadata_export_mode_types.keys, :required => false, :desc => N_("Specify how to handle metadata")
37
- param :dir, String, :required => false, :desc => N_("The directory within Git repo")
28
+ param_group :foreman_template_sync_params
38
29
  def export
39
- ForemanTemplates::TemplateExporter.new({
40
- verbose: params['verbose'],
41
- repo: params['repo'],
42
- branch: params['branch'],
43
- filter: params['filter'],
44
- negate: params['negate'],
45
- metadata_export_mode: params['metadata_export_mode'],
46
- dir: params['dir']
47
- }).export!
30
+ ForemanTemplates::TemplateExporter.new(template_export_params).export!
48
31
  render :json => { :message => _('Success') }
49
- rescue => e
32
+ rescue StandardError => e
50
33
  logger.debug e
51
- render :json => { :message => (_('Something went wrong during export: %s') % e.message) }, :status => 500
34
+ render :json => { :message => (_('Something went wrong during export: %s') % e.message) }, :status => :internal_server_error
52
35
  end
53
36
  end
54
37
  end
@@ -0,0 +1,37 @@
1
+ module Foreman
2
+ module Controller
3
+ module Parameters
4
+ module TemplateParams
5
+ extend ActiveSupport::Concern
6
+
7
+ class_methods do
8
+ def filter_params_list
9
+ %i(verbose repo branch dirname filter negate metadata_export_mode dirname)
10
+ end
11
+
12
+ def extra_import_params
13
+ %i(associate force prefix lock)
14
+ end
15
+
16
+ def extra_export_params
17
+ [:metadata_export_mode]
18
+ end
19
+
20
+ def template_params_filter(extra_params = [])
21
+ Foreman::ParameterFilter.new(Hash).tap do |filter|
22
+ filter.permit filter_params_list.concat(extra_params)
23
+ end
24
+ end
25
+ end
26
+
27
+ def template_import_params
28
+ self.class.template_params_filter(self.class.extra_import_params).filter_params(params, parameter_filter_context, :none)
29
+ end
30
+
31
+ def template_export_params
32
+ self.class.template_params_filter(self.class.extra_export_params).filter_params(params, parameter_filter_context, :none)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -19,20 +19,22 @@ class Setting
19
19
  def self.load_defaults
20
20
  return unless super
21
21
 
22
- %w(template_sync_filter template_sync_branch).each { |s| Setting::BLANK_ATTRS << s }
22
+ %w(template_sync_filter template_sync_branch template_sync_prefix).each { |s| Setting::BLANK_ATTRS << s }
23
+ Setting::NOT_STRIPPED << 'template_sync_prefix'
23
24
 
24
25
  self.transaction do
25
26
  [
26
27
  self.set('template_sync_verbose', N_('Choose verbosity for Rake task importing templates'), false, N_('Verbosity')),
27
- self.set('template_sync_associate', N_('Associate templates to OS'), 'new', N_('Associate'), nil, { :collection => Proc.new { self.associate_types } }),
28
- self.set('template_sync_prefix', N_('The string all imported templates should begin with'), "Community ", N_('Prefix')),
28
+ self.set('template_sync_associate', N_('Associate templates to OS, organization and location'), 'new', N_('Associate'), nil, { :collection => Proc.new { self.associate_types } }),
29
+ self.set('template_sync_prefix', N_('The string all imported templates should begin with'), "", N_('Prefix')),
29
30
  self.set('template_sync_dirname', N_('The directory within the Git repo containing the templates'), '/', N_('Dirname')),
30
31
  self.set('template_sync_filter', N_('Import or export names matching this regex (case-insensitive; snippets are not filtered)'), nil, N_('Filter')),
31
- self.set('template_sync_repo', N_('Default Git repo to sync from'), 'https://github.com/theforeman/community-templates.git', N_('Repo')),
32
+ self.set('template_sync_repo', N_('Target path to import and export. Different protocols can be used, e.g. /tmp/dir, git://example.com, https://example.com, ssh://example.com'), 'https://github.com/theforeman/community-templates.git', N_('Repo')),
32
33
  self.set('template_sync_negate', N_('Negate the prefix (for purging) / filter (for importing/exporting)'), false, N_('Negate')),
33
34
  self.set('template_sync_branch', N_('Default branch in Git repo'), nil, N_('Branch')),
34
35
  self.set('template_sync_metadata_export_mode', N_('Default metadata export mode, refresh re-renders metadata, keep will keep existing metadata, remove exports template withou metadata'), 'refresh', N_('Metadata export mode'), nil, { :collection => Proc.new { self.metadata_export_mode_types } }),
35
36
  self.set('template_sync_force', N_('Should importing overwrite locked templates?'), false, N_('Force import')),
37
+ self.set('template_sync_lock', N_('Should importing lock templates?'), false, N_('Lock templates')),
36
38
  ].compact.each { |s| self.create! s.update(:category => "Setting::TemplateSync") }
37
39
  end
38
40
 
@@ -1,18 +1,16 @@
1
- class NoKindError < RuntimeError; end
2
- class MissingKindError < RuntimeError; end
3
-
4
1
  module ForemanTemplates
5
2
  class TemplateImporter < Action
6
3
  attr_accessor :metadata, :name, :text
7
4
 
8
5
  def self.setting_overrides
9
- super + %i(associate force)
6
+ super + %i(associate force lock)
10
7
  end
11
8
 
12
9
  def initialize(args = {})
13
10
  super
14
11
  @verbose = parse_bool(@verbose)
15
12
  @force = parse_bool(@force)
13
+ @lock = parse_bool(@lock)
16
14
  end
17
15
 
18
16
  def import!
@@ -52,55 +50,59 @@ module ForemanTemplates
52
50
  text = File.read(template)
53
51
  result_lines << 'Parsing: ' + template.gsub(/#{@dir}#{@dirname}/, '') if @verbose
54
52
 
55
- metadata = parse_metadata(text)
56
- metadata['associate'] = @associate
53
+ metadata = Template.parse_metadata(text)
57
54
 
58
55
  # Get the name and filter
59
- filename = template.split('/').last
60
- title = filename.split('.').first
61
- name = metadata['name'] || title
62
- name = auto_prefix(name)
56
+ name = metadata['name']
57
+ name = auto_prefix(name)
63
58
  if @filter
64
59
  matching = name.match(/#{@filter}/i)
65
60
  matching = !matching if @negate
66
- next unless matching
61
+ unless matching
62
+ result_lines << "Skipping template '#{name}' since it's name is matching filter condition" if @verbose
63
+ next
64
+ end
67
65
  end
68
66
 
67
+ options = { :force => @force, :associate => @associate, :lock => @lock }
68
+ template_type = 'Unknown template type'
69
69
  begin
70
- # Expects a return of { :diff, :status, :result, :errors }
71
- data = if metadata['model'].present?
72
- metadata['model'].constantize.import!(name, text, metadata, @force)
73
- else
74
- # For backwards-compat before "model" metadata was added
75
- case metadata['kind']
76
- when 'ptable'
77
- Ptable.import!(name, text, metadata, @force)
78
- when 'job_template'
79
- # TODO: update REX templates to have `model` and delete this
80
- update_job_template(name, text)
81
- else
82
- ProvisioningTemplate.import!(name, text, metadata, @force)
83
- end
84
- end
85
-
86
- if data[:diff].nil? && data[:old].present? && data[:new].present?
87
- data[:diff] = calculate_diff(data[:old], data[:new])
70
+ if metadata.key?('model')
71
+ template_type = metadata['model'].constantize
72
+ else
73
+ result_lines << "Metadata for template '#{name}' do not specify 'model', import failed"
74
+ next
75
+ end
76
+
77
+ template = template_type.import_without_save(name, text, options)
78
+
79
+ data = {}
80
+ if template.template_changed?
81
+ data[:old] = template.template_was
82
+ data[:new] = template.template
83
+ if data[:diff].nil? && data[:old].present? && data[:new].present?
84
+ data[:diff] = calculate_diff(data[:old], data[:new])
85
+ end
88
86
  end
89
87
 
88
+ if options[:force]
89
+ template.ignore_locking { template.save! }
90
+ else
91
+ template.save!
92
+ end
93
+
94
+ template_type = template.class.model_name.human
95
+ data[:status] = template.errors.blank? ? "#{template_type} '#{name}' import successful" : "#{template_type} '#{name}' import failed"
96
+ data[:errors] = template.errors.full_messages
97
+
90
98
  if @verbose
91
- result_lines << data[:result]
92
99
  result_lines << data[:diff] unless data[:diff].nil?
93
100
  end
94
- result_lines << status_to_text(data[:status], name)
101
+ result_lines << data[:status]
95
102
  result_lines << data[:errors] unless data[:errors].empty?
96
- rescue MissingKindError
97
- result_lines << " Skipping: '#{name}' - No template kind or model detected"
98
- next
99
- rescue NoKindError
100
- result_lines << " Skipping: '#{name}' - Unknown template kind '#{metadata['kind']}'"
101
- next
102
- rescue NameError
103
- result_lines << " Skipping: '#{name}' - Unknown template model '#{metadata['model']}'"
103
+ rescue => e
104
+ Foreman::Logging.exception 'error during template import', e, :level => :debug
105
+ result_lines << "#{template_type} '#{name}' import failed - #{e.message}"
104
106
  next
105
107
  end
106
108
  end
@@ -119,65 +121,19 @@ module ForemanTemplates
119
121
  end
120
122
  end
121
123
 
122
- def parse_metadata(text)
123
- # Pull out the first erb comment only - /m is for a multiline regex
124
- extracted = text.match(/<%\#[\t a-z0-9=:]*(.+?).-?%>/m)
125
- extracted.nil? ? {} : YAML.load(extracted[1])
126
- end
127
-
128
- def update_job_template(name, text)
129
- file = name.gsub(/^#{@prefix}/, '')
130
- puts 'Deprecation warning: JobTemplate support is moving to the Remote Execution plugin'
131
- puts "- please add 'model: JobTemplate' to the metadata in '#{file}' to call the right method"
132
-
133
- unless defined?(JobTemplate)
134
- return {
135
- :status => false,
136
- :result => 'Skipping job template import, remote execution plugin is not installed.'
137
- }
138
- end
139
- template = JobTemplate.import(
140
- text.sub(/^name: .*$/, "name: #{name}"),
141
- :update => true
142
- )
143
-
144
- c_or_u = template.new_record? ? 'Created' : 'Updated'
145
- id_string = ('id' + template.id) rescue ''
146
-
147
- if template.template != template.template_was
148
- diff = Diffy::Diff.new(
149
- template.template_was,
150
- template.template,
151
- :include_diff_info => true
152
- ).to_s(:color)
153
- end
154
-
155
- result = " #{c_or_u} Template #{id_string}:#{name}"
156
- { :diff => diff, :status => template.save, :result => result }
157
- end
158
-
159
124
  def purge!
160
125
  clause = "name #{@negate ? 'NOT ' : ''}LIKE ?"
161
126
  ProvisioningTemplate.where(clause, "#{@prefix}%").each do |template|
162
127
  puts template if @verbose
163
128
  template.destroy
164
129
  end
165
- end # :purge
130
+ # :purge
131
+ end
166
132
 
167
133
  private
168
134
 
169
135
  def parse_bool(bool_name)
170
136
  bool_name.is_a?(String) ? bool_name != 'false' : bool_name
171
137
  end
172
-
173
- def status_to_text(status, name)
174
- msg = "#{name} - import "
175
- msg << if status
176
- "success"
177
- else
178
- 'failure'
179
- end
180
- msg
181
- end
182
138
  end
183
139
  end
@@ -10,12 +10,12 @@ module ForemanTemplates
10
10
  engine_name 'foreman_templates'
11
11
 
12
12
  initializer 'foreman_templates.load_default_settings', :before => :load_config_initializers do
13
- require_dependency File.expand_path('../../../app/models/setting/template_sync.rb', __FILE__) if (Setting.table_exists? rescue(false))
13
+ require_dependency File.expand_path('../../app/models/setting/template_sync.rb', __dir__) if (Setting.table_exists? rescue(false))
14
14
  end
15
15
 
16
16
  initializer 'foreman_templates.register_plugin', :before => :finisher_hook do
17
17
  Foreman::Plugin.register :foreman_templates do
18
- requires_foreman '>= 1.15'
18
+ requires_foreman '>= 1.18'
19
19
 
20
20
  apipie_documented_controllers ["#{ForemanTemplates::Engine.root}/app/controllers/api/v2/*.rb"]
21
21
 
@@ -30,15 +30,5 @@ module ForemanTemplates
30
30
  add_all_permissions_to_default_roles
31
31
  end
32
32
  end
33
-
34
- config.to_prepare do
35
- begin
36
- Template.send(:include, ForemanTemplates::TemplateImport)
37
- Ptable.send(:include, ForemanTemplates::PtableImport)
38
- ProvisioningTemplate.send(:include, ForemanTemplates::ProvisioningTemplateImport)
39
- rescue => e
40
- puts "#{ForemanTemplates::ENGINE_NAME}: skipping engine hook (#{e})"
41
- end
42
- end
43
33
  end
44
34
  end
@@ -1,3 +1,3 @@
1
1
  module ForemanTemplates
2
- VERSION = '5.0.1'.freeze
2
+ VERSION = '6.0.0'.freeze
3
3
  end
@@ -2,6 +2,7 @@
2
2
  namespace :templates do
3
3
  desc 'Import templates according to settings'
4
4
  task :import => :environment do
5
+ ActiveSupport::Deprecation.warn "You are using a deprecated behavior, 'rake templates:import' will be removed in a future version. Please use appropriate API endpoint for this functionality"
5
6
  if Rake.application.top_level_tasks.include?('templates:sync')
6
7
  ActiveSupport::Deprecation.warn('templates:sync task has been renamed to templates:import and will be removed in a future version')
7
8
  end
@@ -13,6 +14,7 @@ namespace :templates do
13
14
  # * dirname => The directory within the git tree containing the templates [/]
14
15
  # * filter => Import names matching this regex (case-insensitive; snippets are not filtered)
15
16
  # * associate => Associate to OS's, Locations & Organizations. Options are: always, new or never [new]
17
+ # * lock => Lock imported templates [false]
16
18
 
17
19
  User.current = User.anonymous_admin
18
20
 
@@ -24,6 +26,7 @@ namespace :templates do
24
26
  dirname: ENV['dirname'],
25
27
  filter: ENV['filter'],
26
28
  associate: ENV['associate'],
29
+ lock: ENV['lock'],
27
30
  }).import!
28
31
 
29
32
  puts results.join("\n")
@@ -33,6 +36,7 @@ namespace :templates do
33
36
 
34
37
  desc 'Export templates according to settings'
35
38
  task :export => :environment do
39
+ ActiveSupport::Deprecation.warn "You are using a deprecated behavior, 'rake templates:export' will be removed in a future version. Please use appropriate API endpoint for this functionality"
36
40
  User.current = User.anonymous_admin
37
41
 
38
42
  ForemanTemplates::TemplateExporter.new({
@@ -51,6 +55,7 @@ namespace :templates do
51
55
 
52
56
  desc 'Purge unwanted templates from foreman'
53
57
  task :purge => :environment do
58
+ ActiveSupport::Deprecation.warn "You are using a deprecated behavior, 'rake templates:purge' will be removed in a future version. Please use appropriate API endpoint for this functionality"
54
59
  User.current = User.anonymous_admin
55
60
 
56
61
  ForemanTemplates::TemplateImporter.new({
@@ -92,7 +97,7 @@ namespace :foreman_templates do
92
97
  "#{ForemanTemplates::Engine.root}/lib/**/*.rb",
93
98
  "#{ForemanTemplates::Engine.root}/test/**/*.rb"]
94
99
  end
95
- rescue
100
+ rescue StandardError
96
101
  puts 'Rubocop not loaded.'
97
102
  end
98
103
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_templates
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.1
4
+ version: 6.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Greg Sutcliffe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-05-31 00:00:00.000000000 Z
11
+ date: 2018-04-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: diffy
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  description: Engine to synchronise provisioning templates from GitHub
42
56
  email: gsutclif@redhat.com
43
57
  executables: []
@@ -50,9 +64,7 @@ files:
50
64
  - README.md
51
65
  - Rakefile
52
66
  - app/controllers/api/v2/template_controller.rb
53
- - app/models/concerns/foreman_templates/provisioning_template_import.rb
54
- - app/models/concerns/foreman_templates/ptable_import.rb
55
- - app/models/concerns/foreman_templates/template_import.rb
67
+ - app/controllers/concerns/foreman/controller/parameters/template_params.rb
56
68
  - app/models/setting/template_sync.rb
57
69
  - app/services/foreman_templates/action.rb
58
70
  - app/services/foreman_templates/cleaner.rb
@@ -83,7 +95,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
95
  version: '0'
84
96
  requirements: []
85
97
  rubyforge_project:
86
- rubygems_version: 2.4.5
98
+ rubygems_version: 2.6.8
87
99
  signing_key:
88
100
  specification_version: 4
89
101
  summary: Template-syncing engine for Foreman
@@ -1,94 +0,0 @@
1
- module ForemanTemplates
2
- module ProvisioningTemplateImport
3
- extend ActiveSupport::Concern
4
-
5
- module ClassMethods
6
- def import!(name, text, metadata, force = false)
7
- # Check for snippet type
8
- return import_snippet!(name, text, force) if metadata['snippet'] || metadata['kind'] == 'snippet'
9
-
10
- # Get template type
11
- kind = TemplateKind.find_by(name: metadata['kind'])
12
- raise NoKindError unless kind
13
-
14
- # Data
15
- template = ProvisioningTemplate.where(:name => name).first_or_initialize
16
- data = {
17
- :template => text,
18
- :snippet => false,
19
- :template_kind_id => kind.id
20
- }
21
- oses = map_metadata(metadata, 'oses')
22
- locations = map_metadata(metadata, 'locations')
23
- organizations = map_metadata(metadata, 'organizations')
24
-
25
- # Printout helpers
26
- c_or_u = template.new_record? ? 'Creating' : 'Updating'
27
- id_string = template.new_record? ? '' : "id #{template.id}"
28
- if template.locked? && !template.new_record? && !force
29
- return { :diff => nil,
30
- :status => false,
31
- :result => "Skipping Template #{id_string}:#{name} - template is locked" }
32
- end
33
-
34
- associate_metadata data, template, metadata, oses, organizations, locations
35
-
36
- diff = nil
37
- status = nil
38
- if template_changed?(data, template)
39
- diff = create_diff(data, template)
40
- template.ignore_locking do
41
- status = template.update_attributes(data)
42
- end
43
- result = build_associations_result c_or_u, id_string, name, oses, organizations, locations
44
- else
45
- status = true
46
- result = " No change to Template #{id_string}:#{name}"
47
- end
48
-
49
- { :diff => diff, :status => status, :result => result, :errors => template.errors }
50
- end
51
-
52
- def associate_metadata(data, template, metadata, oses, organizations, locations)
53
- if (metadata['associate'] == 'new' && template.new_record?) || (metadata['associate'] == 'always')
54
- data[:operatingsystem_ids] = oses.map(&:id)
55
- data[:location_ids] = locations.map(&:id)
56
- data[:organization_ids] = organizations.map(&:id)
57
- end
58
- data
59
- end
60
-
61
- def build_associations_result(c_or_u, id_string, name, oses, organizations, locations)
62
- res = " #{c_or_u} Template #{id_string}:#{name}"
63
- res += "\n Operatingsystem Associations:\n - #{oses.map(&:fullname).join("\n - ")}" unless oses.empty?
64
- res += "\n Organizations Associations:\n - #{organizations.map(&:name).join("\n - ")}" unless organizations.empty?
65
- res += "\n Location Associations:\n - #{locations.map(&:name).join("\n - ")}" unless locations.empty?
66
- res
67
- end
68
-
69
- def create_diff(data, template)
70
- if template_content_changed?(template.template, data[:template])
71
- Diffy::Diff.new(
72
- template.template,
73
- data[:template],
74
- :include_diff_info => true
75
- ).to_s(:color)
76
- else
77
- nil
78
- end
79
- end
80
-
81
- def template_content_changed?(template_template, data_template)
82
- template_template != data_template
83
- end
84
-
85
- def associations_changed?(data)
86
- !(data[:operatingsystem_ids] || data[:location_ids] || data[:organization_ids]).nil?
87
- end
88
-
89
- def template_changed?(data, template)
90
- template_content_changed?(template.template, data[:template]) || associations_changed?(data)
91
- end
92
- end
93
- end
94
- end
@@ -1,89 +0,0 @@
1
- module ForemanTemplates
2
- module PtableImport
3
- extend ActiveSupport::Concern
4
-
5
- module ClassMethods
6
- def import!(name, text, metadata, force = false)
7
- # Check for snippet type
8
- return import_snippet!(name, text, force) if metadata['snippet']
9
-
10
- # Data
11
- ptable = Ptable.where(:name => name).first_or_initialize
12
- data = {
13
- :layout => text
14
- }
15
- oses = map_metadata(metadata, 'oses')
16
- locations = map_metadata(metadata, 'locations')
17
- organizations = map_metadata(metadata, 'organizations')
18
-
19
- # Printout helpers
20
- c_or_u = ptable.new_record? ? 'Creating' : 'Updating'
21
- id_string = ptable.new_record? ? '' : "id #{ptable.id}"
22
- if ptable.locked? && !ptable.new_record? && !force
23
- return { :diff => nil,
24
- :status => false,
25
- :result => "Skipping Partition Table #{id_string}:#{name} - partition table is locked" }
26
- end
27
-
28
- associate_metadata data, ptable, metadata, oses, organizations, locations
29
-
30
- diff = nil
31
- status = nil
32
- if ptable_changed?(data, ptable)
33
- diff = create_diff(data, ptable)
34
- ptable.ignore_locking do
35
- status = ptable.update_attributes(data)
36
- end
37
- result = build_associations_result c_or_u, id_string, name, oses, organizations, locations
38
- else
39
- status = true
40
- result = " No change to Ptable #{id_string}:#{name}"
41
- end
42
- { :diff => diff, :status => status, :result => result, :errors => ptable.errors }
43
- end
44
-
45
- def associate_metadata(data, ptable, metadata, oses, organizations, locations)
46
- if (metadata['associate'] == 'new' && ptable.new_record?) || (metadata['associate'] == 'always')
47
- data[:operatingsystem_ids] = oses.map(&:id)
48
- data[:os_family] = oses.map(&:family).uniq.first
49
- data[:location_ids] = locations.map(&:id)
50
- data[:organization_ids] = organizations.map(&:id)
51
- end
52
- data
53
- end
54
-
55
- def ptable_content_changed?(data_layout, ptable_layout)
56
- data_layout != ptable_layout
57
- end
58
-
59
- def associations_changed?(data)
60
- !(data[:os_family] || data[:location_ids] || data[:organization_ids]).nil?
61
- end
62
-
63
- def create_diff(data, ptable)
64
- if ptable_content_changed?(data[:layout], ptable.layout)
65
- Diffy::Diff.new(
66
- ptable.layout,
67
- data[:layout],
68
- :include_diff_info => true
69
- ).to_s(:color)
70
- else
71
- nil
72
- end
73
- end
74
-
75
- def build_associations_result(c_or_u, id_string, name, oses, organizations, locations)
76
- res = " #{c_or_u} Ptable #{id_string}:#{name}"
77
- res += "\n Operatingsystem Family:\n - #{oses.map(&:family).uniq.first}" unless oses.empty?
78
- res += "\n Operatingsystem Associations:\n - #{oses.map(&:fullname).join("\n - ")}" unless oses.empty?
79
- res += "\n Organizations Associations:\n - #{organizations.map(&:name).join("\n - ")}" unless organizations.empty?
80
- res += "\n Location Associations:\n - #{locations.map(&:name).join("\n - ")}" unless locations.empty?
81
- res
82
- end
83
-
84
- def ptable_changed?(data, ptable)
85
- ptable_content_changed?(data[:layout], ptable.layout) || associations_changed?(data)
86
- end
87
- end
88
- end
89
- end
@@ -1,65 +0,0 @@
1
- module ForemanTemplates
2
- module TemplateImport
3
- extend ActiveSupport::Concern
4
-
5
- module ClassMethods
6
- def import_snippet!(name, text, force = false)
7
- # Data
8
- snippet = self.where(:name => name).first_or_initialize
9
- data = {
10
- :template => text,
11
- :snippet => true
12
- }
13
-
14
- # Printout helpers
15
- c_or_u = snippet.new_record? ? 'Creating' : 'Updating'
16
- id_string = snippet.new_record? ? '' : "id #{snippet.id}"
17
-
18
- if snippet.locked? && !snippet.new_record? && !force
19
- return { :diff => nil,
20
- :status => false,
21
- :result => "Skipping snippet #{id_string}:#{name} - template is locked" }
22
- end
23
-
24
- status = nil
25
- if data[:template] != snippet.template
26
- diff = Diffy::Diff.new(
27
- snippet.template,
28
- data[:template],
29
- :include_diff_info => true
30
- ).to_s(:color)
31
- snippet.ignore_locking do
32
- status = snippet.update_attributes(data)
33
- end
34
- result = " #{c_or_u} Snippet #{id_string}:#{name}"
35
- else
36
- diff = nil
37
- status = true
38
- result = " No change to Snippet #{id_string}:#{name}"
39
- end
40
- { :diff => diff, :status => status, :result => result, :errors => snippet.errors }
41
- end
42
-
43
- def map_metadata(metadata, param)
44
- if metadata[param]
45
- case param
46
- when 'oses'
47
- metadata[param].map do |os|
48
- Operatingsystem.all.map { |db| db.to_label =~ /^#{os}/ ? db : nil }
49
- end.flatten.compact
50
- when 'locations'
51
- metadata[param].map do |loc|
52
- User.current.my_locations.map { |db| db.name =~ /^#{loc}/ ? db : nil }
53
- end.flatten.compact
54
- when 'organizations'
55
- metadata[param].map do |org|
56
- User.current.my_organizations.map { |db| db.name =~ /^#{org}/ ? db : nil }
57
- end.flatten.compact
58
- end
59
- else
60
- []
61
- end
62
- end
63
- end
64
- end
65
- end