foreman_templates 7.0.5 → 9.0.1

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.
Files changed (48) hide show
  1. checksums.yaml +5 -5
  2. data/app/controllers/api/v2/template_controller.rb +8 -2
  3. data/app/controllers/concerns/foreman/controller/parameters/template_params.rb +22 -2
  4. data/app/controllers/ui_template_syncs_controller.rb +1 -1
  5. data/app/models/setting/template_sync.rb +12 -2
  6. data/app/services/foreman_templates/export_result.rb +20 -29
  7. data/app/services/foreman_templates/parse_result.rb +1 -0
  8. data/app/services/foreman_templates/template_exporter.rb +52 -39
  9. data/app/services/foreman_templates/template_importer.rb +20 -4
  10. data/app/views/template_syncs/index.html.erb +6 -2
  11. data/app/views/ui_template_syncs/template_export_result.rabl +4 -4
  12. data/db/migrate/20180627134929_change_lock_setting.rb +5 -0
  13. data/lib/foreman_templates/engine.rb +6 -0
  14. data/lib/foreman_templates/version.rb +1 -1
  15. data/package.json +15 -21
  16. data/webpack/__mocks__/foremanReact/components/Layout/LayoutSelectors.js +4 -0
  17. data/webpack/__mocks__/foremanReact/components/common/forms/ForemanForm.js +2 -0
  18. data/webpack/components/NewTemplateSync/__fixtures__/templateSyncSettings.fixtures.js +4 -4
  19. data/webpack/components/NewTemplateSync/__tests__/__snapshots__/NewTemplateSync.test.js.snap +2 -2
  20. data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/NewTemplateSyncForm.js +89 -53
  21. data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/NewTemplateSyncFormSelectors.js +10 -13
  22. data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/__tests__/NewTemplateSyncFormSelectors.test.js +1 -19
  23. data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/__tests__/__snapshots__/NewTemplateSyncFormSelectors.test.js.snap +7 -36
  24. data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/index.js +7 -16
  25. data/webpack/components/NewTemplateSync/components/SyncSettingField.js +5 -11
  26. data/webpack/components/NewTemplateSync/components/SyncSettingFields.js +8 -25
  27. data/webpack/components/NewTemplateSync/components/TextButtonField/index.js +27 -20
  28. data/webpack/components/NewTemplateSync/components/__tests__/SyncSettingField.test.js +2 -1
  29. data/webpack/components/NewTemplateSync/components/__tests__/SyncSettingFields.test.js +1 -0
  30. data/webpack/components/NewTemplateSync/components/__tests__/TextButtonField.test.js +4 -4
  31. data/webpack/components/NewTemplateSync/components/__tests__/__snapshots__/SyncSettingField.test.js.snap +18 -27
  32. data/webpack/components/NewTemplateSync/components/__tests__/__snapshots__/SyncSettingFields.test.js.snap +5 -3
  33. data/webpack/components/NewTemplateSync/components/__tests__/__snapshots__/TextButtonField.test.js.snap +8 -91
  34. data/webpack/components/TemplateSyncResult/__fixtures__/templateSyncResult.fixtures.js +2 -2
  35. data/webpack/components/TemplateSyncResult/__tests__/__snapshots__/TemplateSyncResult.test.js.snap +3 -1
  36. data/webpack/components/TemplateSyncResult/__tests__/__snapshots__/TemplateSyncResultReducer.test.js.snap +3 -1
  37. data/webpack/components/TemplateSyncResult/components/SyncResultList.js +2 -2
  38. data/webpack/components/TemplateSyncResult/components/SyncedTemplate/__snapshots__/helpers.test.js.snap +37 -0
  39. data/webpack/components/TemplateSyncResult/components/SyncedTemplate/helpers.js +21 -11
  40. data/webpack/components/TemplateSyncResult/components/SyncedTemplate/helpers.test.js +21 -0
  41. data/webpack/components/TemplateSyncResult/components/__tests__/__snapshots__/SyncResultList.test.js.snap +8 -6
  42. data/webpack/components/TemplateSyncResult/components/__tests__/__snapshots__/SyncedTemplate.test.js.snap +39 -15
  43. data/webpack/testSetup.js +2 -1
  44. metadata +8 -8
  45. data/webpack/__mocks__/foremanReact/components/common/forms/Form.js +0 -2
  46. data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/NewTemplateSyncFormConstants.js +0 -1
  47. data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/__tests__/NewTemplateSyncForm.test.js +0 -42
  48. data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/__tests__/__snapshots__/NewTemplateSyncForm.test.js.snap +0 -186
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 773f26f24c7e56569b70ae180164487a804c89a6
4
- data.tar.gz: 13138a1fd87a675c222333e57e7c2ea78a1489c0
2
+ SHA256:
3
+ metadata.gz: 46560d67a9e22719b19e71c43a0298d960ef8859a37fa0fdba12d0a2ea91fa21
4
+ data.tar.gz: b57fa4cf54bff7ca216d6e3a2abbbe77215e078ee7feb896053603f3d56a07fe
5
5
  SHA512:
6
- metadata.gz: eecbb9e4993ab19b071dfa052290e45b9ee14d50e62b99984de31ea8f28a3a9c48b19bbc06ce17ccab1fdccd325e8016dbc2e1ea7d1a5c13c9520fbd096498d0
7
- data.tar.gz: c2091508b18ecb0396564782b809e0e9e69c1489389a0cee5397c7c9a39dab1c2e46954486efd75de2f41b41a01090d8b0db03984b60dc392edf923c9d41b9fc
6
+ metadata.gz: 6422b8cd5feb8b24e541dfa819aa8f063f65385fdfe4ad884e48474d1e76ad7d327c13e60336803e48de9034a299b6a01bc727966384e75e73c9162fc29cf069
7
+ data.tar.gz: ddb404bc9683c683403c4a401ccacb2118dadc197b998272f70192525738fa68746f290264ead24c42a2c4ca97d49db115aafe6f8e3cac2c416eacc6ca420230
@@ -3,6 +3,10 @@ module Api
3
3
  class TemplateController < ::Api::V2::BaseController
4
4
  include ::Foreman::Controller::Parameters::TemplateParams
5
5
 
6
+ resource_description do
7
+ resource_id 'templates'
8
+ end
9
+
6
10
  def_param_group :foreman_template_sync_params do
7
11
  param :branch, String, :required => false, :desc => N_("Branch in Git repo.")
8
12
  param :repo, String, :required => false, :desc => N_("Override the default repo from settings.")
@@ -15,7 +19,7 @@ module Api
15
19
  param :prefix, String, :required => false, :desc => N_("The string all imported templates should begin with.")
16
20
  param :associate, Setting::TemplateSync.associate_types.keys, :required => false, :desc => N_("Associate to OS's, Locations & Organizations. Options are: always, new or never.")
17
21
  param :force, :bool, :required => false, :desc => N_("Update templates that are locked")
18
- param :lock, :bool, :required => false, :desc => N_("Lock imported templates")
22
+ param :lock, Setting::TemplateSync.lock_types.keys + ["true", "false", "0", "1"], :required => false, :desc => N_("Lock imported templates")
19
23
  param :verbose, :bool, :required => false, :desc => N_("Show template diff in response")
20
24
  param_group :foreman_template_sync_params
21
25
  param_group :taxonomies, ::Api::V2::BaseController
@@ -29,11 +33,13 @@ module Api
29
33
 
30
34
  api :POST, "/templates/export", N_("Initiate Export")
31
35
  param :metadata_export_mode, Setting::TemplateSync.metadata_export_mode_types.keys, :required => false, :desc => N_("Specify how to handle metadata")
36
+ param :commit_msg, String, :desc => N_("Custom commit message for templates export")
32
37
  param_group :foreman_template_sync_params
33
38
  param_group :taxonomies, ::Api::V2::BaseController
34
39
  def export
35
40
  @result = ForemanTemplates::TemplateExporter.new(template_export_params).export!
36
- render :json => { :message => @result.to_h }, :status => @result.exported ? 200 : 500
41
+ @result[:templates] = @result[:templates].map(&:to_h)
42
+ render :json => { :message => @result }, :status => @result[:error] ? 500 : 200
37
43
  end
38
44
  end
39
45
  end
@@ -15,7 +15,7 @@ module Foreman
15
15
  end
16
16
 
17
17
  def extra_export_params
18
- [:metadata_export_mode]
18
+ %i(metadata_export_mode commit_msg)
19
19
  end
20
20
 
21
21
  def template_params_filter(extra_params = [])
@@ -34,7 +34,27 @@ module Foreman
34
34
  end
35
35
 
36
36
  def template_import_params
37
- add_taxonomy_params(base_import_params(:none))
37
+ transform_lock_param add_taxonomy_params(base_import_params(:none))
38
+ end
39
+
40
+ def transform_lock_param(params)
41
+ lock = params[:lock]
42
+ return params if lock.nil?
43
+
44
+ if lock == "true" || lock.is_a?(TrueClass) || lock.to_s == "1"
45
+ log_deprecated_param(lock)
46
+ params[:lock] = "lock"
47
+ end
48
+
49
+ if lock == "false" || lock.is_a?(FalseClass) || lock.to_s == "0"
50
+ log_deprecated_param(lock)
51
+ params[:lock] = "unlock"
52
+ end
53
+ params
54
+ end
55
+
56
+ def log_deprecated_param(value)
57
+ Logging.logger('app').warn "Using '#{value}' as a value for lock when syncing templates is deprecated and will be removed in the future."
38
58
  end
39
59
 
40
60
  def template_export_params
@@ -18,7 +18,7 @@ class UiTemplateSyncsController < ApplicationController
18
18
  end
19
19
 
20
20
  def export
21
- @result = ForemanTemplates::TemplateExporter.new(ui_template_export_params).export!
21
+ @result = OpenStruct.new ForemanTemplates::TemplateExporter.new(ui_template_export_params).export!
22
22
 
23
23
  if @result.error
24
24
  render_errors [@result.error]
@@ -11,7 +11,7 @@ class Setting
11
11
  end
12
12
 
13
13
  def self.export_stripped_names
14
- %w(metadata_export_mode)
14
+ %w(metadata_export_mode commit_msg)
15
15
  end
16
16
 
17
17
  def self.import_setting_names(except = [])
@@ -38,6 +38,15 @@ class Setting
38
38
  }
39
39
  end
40
40
 
41
+ def self.lock_types
42
+ {
43
+ 'lock' => _('Lock'),
44
+ 'keep_lock_new' => _('Keep, lock new'),
45
+ 'keep' => _('Keep, do not lock new'),
46
+ 'unlock' => _('Unlock')
47
+ }
48
+ end
49
+
41
50
  def self.metadata_export_mode_types
42
51
  {
43
52
  'refresh' => _('Refresh'),
@@ -75,7 +84,8 @@ class Setting
75
84
  self.set('template_sync_branch', N_('Default branch in Git repo'), '', N_('Branch')),
76
85
  self.set('template_sync_metadata_export_mode', N_('Default metadata export mode, refresh re-renders metadata, keep will keep existing metadata, remove exports template without metadata'), 'refresh', N_('Metadata export mode'), nil, { :collection => Proc.new { self.metadata_export_mode_types } }),
77
86
  self.set('template_sync_force', N_('Should importing overwrite locked templates?'), false, N_('Force import')),
78
- self.set('template_sync_lock', N_('Should importing lock templates?'), false, N_('Lock templates')),
87
+ self.set('template_sync_lock', N_('How to handle lock for imported templates?'), 'keep', N_('Lock templates'), nil, { :collection => Proc.new { self.lock_types } }),
88
+ self.set('template_sync_commit_msg', N_('Custom commit message for templates export'), 'Templates export made by a Foreman user', N_('Commit message'))
79
89
  ].compact.each { |s| self.create! s.update(:category => "Setting::TemplateSync") }
80
90
  end
81
91
 
@@ -1,42 +1,33 @@
1
1
  module ForemanTemplates
2
2
  class ExportResult
3
- attr_accessor :exported, :error, :warning
4
- attr_reader :templates, :git_user, :branch, :repo
3
+ attr_reader :template, :name, :template_file, :exported, :additional_info
5
4
 
6
- def initialize(repo, branch, git_user)
7
- @repo = repo
8
- @branch = branch
9
- @git_user = git_user
10
- @error = nil
11
- @warning = nil
12
- @templates = []
13
- @exported = false
14
- end
15
-
16
- def add_exported_templates(templates)
17
- @templates.concat templates
5
+ def initialize(template, exported = true)
6
+ @template = template
7
+ @exported = exported
8
+ @name = template.name
9
+ @template_file = template.template_file
18
10
  end
19
11
 
20
12
  def to_h
21
- { :error => @error,
22
- :warning => @warning,
23
- :repo => @repo,
24
- :branch => @branch,
25
- :git_user => @git_user,
26
- :templates => dumped_files_result }
13
+ {
14
+ :id => template.id,
15
+ :name => @name,
16
+ :exported => @exported,
17
+ :type => template.class.name.underscore,
18
+ :additional_info => @additional_info
19
+ }
27
20
  end
28
21
 
29
- private
30
-
31
- def dumped_files_result
32
- @templates.map { |template| to_template_h template }
22
+ def matching_filter
23
+ generic_info "Skipping, 'name' filtered out based on 'filter' and 'negate' settings"
33
24
  end
34
25
 
35
- def to_template_h(template)
36
- { :id => template.id,
37
- :name => template.name,
38
- :exported => @exported,
39
- :type => template.class.name.underscore }
26
+ def generic_info(additional_msg)
27
+ @exported = false
28
+ @additional_info = additional_msg
29
+ Logging.logger('app').debug "Not exporting #{@template.name}: #{additional_msg}"
30
+ self
40
31
  end
41
32
  end
42
33
  end
@@ -14,6 +14,7 @@ module ForemanTemplates
14
14
  :changed => changed?,
15
15
  :imported => @imported,
16
16
  :additional_errors => @additional_errors,
17
+ :additional_info => @additional_info,
17
18
  :exception => @exception ? @exception.message : nil,
18
19
  :validation_errors => errors.to_h,
19
20
  :file => @template_file,
@@ -1,30 +1,32 @@
1
1
  module ForemanTemplates
2
2
  class TemplateExporter < Action
3
3
  def self.setting_overrides
4
- super + %i(metadata_export_mode)
4
+ super + %i(metadata_export_mode commit_msg)
5
+ end
6
+
7
+ def initialize(args = {})
8
+ super args
9
+ @result_lines = []
5
10
  end
6
11
 
7
12
  def export!
8
- @export_result = ExportResult.new(@repo, @branch, foreman_git_user)
9
13
  if git_repo?
10
14
  export_to_git
11
15
  else
12
16
  export_to_files
13
17
  end
14
-
15
- return @export_result
18
+ export_result
16
19
  end
17
20
 
18
21
  def export_to_files
19
22
  @dir = get_absolute_repo_path
20
23
  verify_path!(@dir)
21
24
  dump_files!
22
- @export_result.exported = true
23
25
  end
24
26
 
25
27
  def export_to_git
26
28
  @dir = Dir.mktmpdir
27
- return @export_result if branch_missing?
29
+ return if branch_missing?
28
30
 
29
31
  git_repo = Git.clone(@repo, @dir)
30
32
  logger.debug "cloned '#{@repo}' to '#{@dir}'"
@@ -33,30 +35,33 @@ module ForemanTemplates
33
35
  dump_files!
34
36
  git_repo.add
35
37
 
36
- status = git_repo.status
37
- if status.added.any? || status.changed.any? || status.deleted.any? || status.untracked.any?
38
- git_repo.commit "Templates export made by Foreman user #{foreman_git_user}"
38
+ new_repo = false
39
+ begin
40
+ status = git_repo.status
41
+ rescue Git::GitExecuteError # no HEAD for repo without commits, git diff-index HEAD fails
42
+ new_repo = true
43
+ end
44
+ if new_repo || status.added.any? || status.changed.any? || status.deleted.any? || status.untracked.any?
45
+ git_repo.commit commit_msg
39
46
  git_repo.push 'origin', branch
40
- @export_result.exported = true
41
47
  else
42
- @export_result.warning = 'No change detected, skipping the commit and push'
48
+ @warning = 'No change detected, skipping the commit and push'
43
49
  end
44
50
  rescue StandardError => e
45
- @export_result.error = e.message
51
+ @error = e.message
46
52
  ensure
47
53
  FileUtils.remove_entry_secure(@dir) if File.exist?(@dir)
48
- @export_result
49
54
  end
50
55
 
51
56
  def setup_git_branch(git_repo)
52
57
  logger.debug "checking out branch '#{@branch}'"
53
- if git_repo.is_branch?(@branch)
58
+ if git_repo.is_branch?(@branch) # local branch
54
59
  git_repo.checkout(@branch)
55
- else
60
+ elsif git_repo.is_remote_branch?(@branch) # if we work with remote branch, checkout and sync
56
61
  git_repo.branch(@branch).checkout
57
- if git_repo.is_remote_branch?(@branch) # if we work with remote branch we need to sync it first
58
- git_repo.reset_hard("origin/#{@branch}")
59
- end
62
+ git_repo.reset_hard("origin/#{@branch}")
63
+ else # neither local nor remote
64
+ git_repo.checkout(@branch, :new_branch => true)
60
65
  end
61
66
  end
62
67
 
@@ -65,22 +70,18 @@ module ForemanTemplates
65
70
  end
66
71
 
67
72
  def dump_files!
68
- templates = templates_to_dump
69
- begin
70
- templates.map do |template|
71
- current_dir = get_dump_dir(template)
72
- FileUtils.mkdir_p current_dir
73
- filename = File.join(current_dir, template.template_file)
74
- File.open(filename, 'w+') do |file|
75
- logger.debug "Writing to file #{filename}"
76
- bytes = file.write template.public_send(export_method)
77
- logger.debug "finished writing #{bytes}"
78
- end
73
+ templates_to_dump.map do |template|
74
+ current_dir = get_dump_dir(template)
75
+ FileUtils.mkdir_p current_dir
76
+ filename = File.join(current_dir, template.template_file)
77
+ File.open(filename, 'w+') do |file|
78
+ logger.debug "Writing to file #{filename}"
79
+ bytes = file.write template.public_send(export_method)
80
+ logger.debug "finished writing #{bytes}"
79
81
  end
80
- rescue StandardError => e
81
- raise PathAccessException, e.message
82
82
  end
83
- @export_result.add_exported_templates templates
83
+ rescue StandardError => e
84
+ raise PathAccessException, e.message
84
85
  end
85
86
 
86
87
  def get_dump_dir(template)
@@ -91,18 +92,23 @@ module ForemanTemplates
91
92
  end
92
93
 
93
94
  def templates_to_dump
94
- base = find_templates
95
- if filter.present?
96
- method = negate ? :reject : :select
97
- base.public_send(method) { |template| template.name.match(/#{filter}/i) }
98
- else
99
- base
95
+ find_templates.each do |template|
96
+ if filter.present?
97
+ exportable = template.name =~ /#{filter}/i ? !negate : negate
98
+ result = ExportResult.new(template, exportable)
99
+ next @result_lines << result.matching_filter unless exportable
100
+
101
+ @result_lines << result
102
+ else
103
+ @result_lines << ExportResult.new(template)
104
+ end
100
105
  end
106
+ @result_lines.select(&:exported).map(&:template)
101
107
  end
102
108
 
103
109
  def branch_missing?
104
110
  if @branch.blank?
105
- @export_result.error = "Please specify a branch when exporting into a git repo"
111
+ @error = "Please specify a branch when exporting into a git repo"
106
112
  return true
107
113
  end
108
114
  false
@@ -124,6 +130,13 @@ module ForemanTemplates
124
130
  end
125
131
  end
126
132
 
133
+ def export_result
134
+ {
135
+ :templates => @result_lines, :repo => @repo, :branch => @branch,
136
+ :git_user => foreman_git_user, :error => @error, :warning => @warning
137
+ }
138
+ end
139
+
127
140
  private
128
141
 
129
142
  def find_templates
@@ -10,7 +10,6 @@ module ForemanTemplates
10
10
  super args
11
11
  @verbose = parse_bool(@verbose)
12
12
  @force = parse_bool(@force)
13
- @lock = parse_bool(@lock)
14
13
  @result_lines = []
15
14
  end
16
15
 
@@ -79,11 +78,28 @@ module ForemanTemplates
79
78
  end
80
79
 
81
80
  def import_options
82
- { :force => @force,
81
+ lock_predicate = lambda do |template|
82
+ case @lock
83
+ when 'lock'
84
+ return true
85
+ when 'unlock'
86
+ return false
87
+ when 'keep'
88
+ return template.new_record? ? false : template.locked
89
+ when 'keep_lock_new'
90
+ return template.new_record? ? true : template.locked
91
+ else
92
+ raise ::Foreman::Exception.new("Unknown lock option type, expected one of #{::Setting::TemplateSync.lock_types.keys}, got #{@lock}")
93
+ end
94
+ end
95
+
96
+ {
97
+ :force => @force,
83
98
  :associate => @associate,
84
- :lock => @lock,
99
+ :lock => lock_predicate,
85
100
  :organization_params => @taxonomies[:organizations],
86
- :location_params => @taxonomies[:locations] }
101
+ :location_params => @taxonomies[:locations]
102
+ }
87
103
  end
88
104
 
89
105
  def template_model(metadata, parse_result)
@@ -1,5 +1,9 @@
1
- <%= webpacked_plugins_js_for :foreman_templates %>
2
- <%= webpacked_plugins_css_for :foreman_templates %>
1
+ <% content_for(:javascripts) do %>
2
+ <%= webpacked_plugins_js_for :foreman_templates %>
3
+ <% end %>
4
+ <% content_for(:stylesheets) do %>
5
+ <%= webpacked_plugins_css_for :foreman_templates %>
6
+ <% end %>
3
7
 
4
8
  <div id="foreman-templates"/>
5
9
 
@@ -1,7 +1,7 @@
1
- object @template
1
+ object @template_result
2
2
 
3
- attributes :name, :template_file
3
+ attributes :name, :template_file, :additional_info
4
4
 
5
- node(false) do |template|
6
- partial "ui_template_syncs/template_attrs", :object => template
5
+ node(false) do |result|
6
+ partial "ui_template_syncs/template_attrs", :object => result.template
7
7
  end
@@ -0,0 +1,5 @@
1
+ class ChangeLockSetting < ActiveRecord::Migration[5.1]
2
+ def up
3
+ Setting.find_by(:name => 'template_sync_lock')&.destroy
4
+ end
5
+ end
@@ -20,6 +20,12 @@ module ForemanTemplates
20
20
  end
21
21
  end
22
22
 
23
+ initializer "foreman_templates.load_app_instance_data" do |app|
24
+ ForemanTemplates::Engine.paths['db/migrate'].existent.each do |path|
25
+ app.config.paths['db/migrate'] << path
26
+ end
27
+ end
28
+
23
29
  initializer 'foreman_templates.register_plugin', :before => :finisher_hook do
24
30
  Foreman::Plugin.register :foreman_templates do
25
31
  requires_foreman '>= 1.24'