foreman_templates 5.0.1 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
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