foreman_templates 7.0.5 → 9.0.1

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