foreman_git_templates 1.0.5 → 2.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.
Files changed (26) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -0
  3. data/Rakefile +4 -2
  4. data/app/controllers/concerns/foreman_git_templates/unattended_controller_extensions.rb +1 -1
  5. data/app/lib/foreman_git_templates/renderer/source/repository.rb +2 -1
  6. data/app/lib/foreman_git_templates/renderer.rb +1 -5
  7. data/app/models/concerns/foreman_git_templates/host_parameter_extensions.rb +2 -2
  8. data/app/models/concerns/foreman_git_templates/orchestration/tftp.rb +12 -2
  9. data/app/services/foreman_git_templates/repository_fetcher.rb +4 -4
  10. data/app/services/foreman_git_templates/repository_reader.rb +8 -1
  11. data/db/migrate/20230203130941_fix_git_templates_settings_category_to_dsl.rb +13 -0
  12. data/lib/foreman_git_templates/engine.rb +14 -7
  13. data/lib/foreman_git_templates/version.rb +1 -1
  14. data/lib/tasks/foreman_git_templates_tasks.rake +0 -3
  15. data/test/controllers/hosts_controller_test.rb +1 -1
  16. data/test/controllers/unattended_controller_test.rb +25 -7
  17. data/test/models/concerns/foreman_git_templates/hostext/operating_system_test.rb +1 -1
  18. data/test/models/concerns/foreman_git_templates/orchestration/tftp_test.rb +44 -15
  19. data/test/models/foreman_git_templates/host_parameter_test.rb +4 -4
  20. data/test/models/foreman_git_templates/host_test.rb +53 -21
  21. data/test/models/foreman_git_templates/snippet_repository_template_test.rb +3 -1
  22. data/test/unit/foreman/renderer/source/repository_test.rb +1 -1
  23. data/test/unit/foreman_git_templates/access_permissions_test.rb +18 -0
  24. data/test/unit/repository_fetcher_test.rb +5 -1
  25. metadata +25 -48
  26. data/app/models/setting/git_templates.rb +0 -26
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ef1542116b039a0e33811e4eaa3c65b3c05da618735f47f9f30fe5dd9b243599
4
- data.tar.gz: fbbd7adb1894aac45862a92653cc2e84667a1ea14a19c2a1e17ab44d882e6358
3
+ metadata.gz: a94d6d6381bf398d3f036ca2fb9fed20c9868140ab53e116d76805e0bee2d30b
4
+ data.tar.gz: 0b7a8fd7ae5d564da6be772161c8f7a4480102d5a950ac573560060eb44f08ea
5
5
  SHA512:
6
- metadata.gz: 3ba5ffceb6a9049d268589824b73bcf9c1d135d05db12242e08473abe3a2aa47fe4aa21129baf27e646e42d1ce7cddad8d7272b23d173c8a3bb82a75d64dec43
7
- data.tar.gz: 9539d07fd4eee73f05d467a5a5f3e2b83d3ff34337b155a96913c53cc69006b25840010d07df79b90ae2f0d219a986e341d094bc4c06b3b80b89525d28938fab
6
+ metadata.gz: cba39a64316baa32786d262f0e94aa173ef164c9325a69b9e698bd6b698ffa9d89bfe7a08353fa259cb044041586b04a112fd5c87acf47a9b838e5dd5903a6f6
7
+ data.tar.gz: e60a95dd0e3ab7da8cdba0752515eb6c324a909779363f492f0d16807fb2432d26f0562957d64ebd8b02ae115969e14ea9fc722ac680f09d0de5cdbd3f392e3a
data/README.md CHANGED
@@ -9,6 +9,7 @@ This is a plugin for Foreman that adds support for using templates from Git repo
9
9
  | Foreman Version | Plugin Version |
10
10
  | --------------- | -------------- |
11
11
  | >= 1.20 | ~> 1.0 |
12
+ | >= 3.9 | ~> 2.0 |
12
13
 
13
14
  ## Installation
14
15
 
data/Rakefile CHANGED
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env rake
2
+ # frozen_string_literal: true
3
+
2
4
  begin
3
5
  require 'bundler/setup'
4
6
  rescue LoadError
@@ -20,7 +22,7 @@ RDoc::Task.new(:rdoc) do |rdoc|
20
22
  rdoc.rdoc_files.include('lib/**/*.rb')
21
23
  end
22
24
 
23
- APP_RAKEFILE = File.expand_path('../test/dummy/Rakefile', __FILE__)
25
+ APP_RAKEFILE = File.expand_path('test/dummy/Rakefile', __dir__)
24
26
 
25
27
  Bundler::GemHelper.install_tasks
26
28
 
@@ -38,7 +40,7 @@ task default: :test
38
40
  begin
39
41
  require 'rubocop/rake_task'
40
42
  RuboCop::RakeTask.new
41
- rescue => _
43
+ rescue StandardError
42
44
  puts 'Rubocop not loaded.'
43
45
  end
44
46
 
@@ -13,7 +13,7 @@ module ForemanGitTemplates
13
13
  template = ForemanGitTemplates::DefaultLocalBootRepositoryTemplate.new(name: 'iPXE')
14
14
  safe_render(template)
15
15
  rescue ForemanGitTemplates::RepositoryReader::MissingFileError
16
- render_ipxe_message(message: _('iPXE default local boot template not found in repository at templates/iPXE/default_local_boot.erb'))
16
+ render_ipxe_message(message: _('iPXE default local boot template not found in repository at templates/iPXE/default_local_boot.erb')) # rubocop:disable Layout/LineLength
17
17
  end
18
18
  end
19
19
 
@@ -5,7 +5,7 @@ module ForemanGitTemplates
5
5
  module Source
6
6
  class Repository < Foreman::Renderer::Source::Base
7
7
  def initialize(template, repository_path)
8
- @template = template
8
+ super(template)
9
9
  @repository_path = repository_path
10
10
  end
11
11
 
@@ -20,6 +20,7 @@ module ForemanGitTemplates
20
20
  private
21
21
 
22
22
  attr_reader :repository_path
23
+
23
24
  delegate :path, to: :template, prefix: true
24
25
  end
25
26
  end
@@ -4,20 +4,16 @@ module ForemanGitTemplates
4
4
  module Renderer
5
5
  REPOSITORY_SOURCE_CLASS = ForemanGitTemplates::Renderer::Source::Repository
6
6
 
7
- # rubocop:disable Metrics/PerceivedComplexity
8
- def get_source(klass: nil, template:, **args)
7
+ def get_source(template:, klass: nil, **args)
9
8
  return super if klass && klass != REPOSITORY_SOURCE_CLASS
10
9
 
11
10
  repository_path = repository_path(args[:host])
12
11
  if repository_path
13
12
  REPOSITORY_SOURCE_CLASS.new(template, repository_path)
14
- elsif !repository_path && Gem::Version.new(SETTINGS[:version].version) < Gem::Version.new('1.23')
15
- super(klass: klass || Foreman::Renderer::Source::Database, template: template, **args)
16
13
  else
17
14
  super
18
15
  end
19
16
  end
20
- # rubocop:enable Metrics/PerceivedComplexity
21
17
 
22
18
  private
23
19
 
@@ -11,9 +11,9 @@ module ForemanGitTemplates
11
11
  private
12
12
 
13
13
  def template_url_is_reachable
14
- RestClient::Request.execute(method: :head, url: value, timeout: Setting::GitTemplates['template_url_validation_timeout'])
14
+ RestClient::Request.execute(method: :head, url: value, timeout: Setting['template_url_validation_timeout'])
15
15
  rescue RestClient::ExceptionWithResponse, URI::InvalidURIError, SocketError => e
16
- errors.add(:value, _('Cannot fetch templates from %{url}: %{error}') % { url: value, error: e.message })
16
+ errors.add(:value, format(_('Cannot fetch templates from %<url>s: %<error>s'), url: value, error: e.message))
17
17
  end
18
18
  end
19
19
  end
@@ -19,15 +19,25 @@ module ForemanGitTemplates
19
19
 
20
20
  private
21
21
 
22
+ # rubocop:todo Metrics/AbcSize
22
23
  def validate_tftp
23
- return super unless host.params['template_url']
24
+ return super unless feasible_for_git_template_rendering?
24
25
  return unless tftp? || tftp6?
25
26
  return unless host.operatingsystem
26
27
 
27
28
  pxe_kind = host.operatingsystem.pxe_loader_kind(host)
28
29
  return unless pxe_kind && host.provisioning_template(kind: pxe_kind).nil?
29
30
 
30
- failure _('No %{kind} template was found for host %{host}. Repository url: %{url}') % { kind: pxe_kind, host: host.name, url: host.params['template_url'] }
31
+ failure format(_('No %<kind>s template was found for host %<host>s. Repository url: %<url>s'),
32
+ kind: pxe_kind, host: host.name, url: host.params['template_url'])
33
+ end
34
+ # rubocop:enable Metrics/AbcSize
35
+
36
+ def feasible_for_git_template_rendering?
37
+ return false unless host.is_a?(Host::Managed)
38
+ return false unless host.params['template_url']
39
+
40
+ true
31
41
  end
32
42
  end
33
43
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'down'
3
+ require 'rest-client'
4
4
 
5
5
  module ForemanGitTemplates
6
6
  class RepositoryFetcher
@@ -9,10 +9,10 @@ module ForemanGitTemplates
9
9
  end
10
10
 
11
11
  def call
12
- Down.download(repository_url)
13
- rescue Down::ResponseError => e
12
+ RestClient::Request.execute(method: :get, url: repository_url, raw_response: true).file
13
+ rescue RestClient::RequestFailed => e
14
14
  raise RepositoryFetcherError, "Cannot fetch repository from #{repository_url}. Response code: #{e.response.code}"
15
- rescue Down::Error => e
15
+ rescue RestClient::Exception => e
16
16
  raise RepositoryFetcherError, "Cannot fetch repository from #{repository_url}, #{e.message}"
17
17
  end
18
18
 
@@ -27,6 +27,7 @@ module ForemanGitTemplates
27
27
 
28
28
  attr_reader :repository_path, :file
29
29
 
30
+ # rubocop:todo Metrics/AbcSize, Metrics/MethodLength
30
31
  def content
31
32
  @content ||= Tar.untar(repository_path) do |tar|
32
33
  return tar.each do |entry|
@@ -39,7 +40,13 @@ module ForemanGitTemplates
39
40
  end
40
41
  rescue Errno::ENOENT, Zlib::GzipFile::Error => e
41
42
  Foreman::Logging.exception("GitTemplates: Cannot read repository from #{repository_path}", e)
42
- raise RepositoryUnreadableError, _('Cannot read repository from %{repository_path}: %{error}') % { repository_path: repository_path, error: e.message }
43
+ raise RepositoryUnreadableError,
44
+ format(
45
+ _('Cannot read repository from %<repository_path>s: %<error>s'),
46
+ repository_path: repository_path,
47
+ error: e.message
48
+ )
43
49
  end
50
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
44
51
  end
45
52
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ class FixGitTemplatesSettingsCategoryToDsl < ActiveRecord::Migration[6.0]
4
+ class MigrationSettings < ActiveRecord::Base
5
+ self.table_name = :settings
6
+ end
7
+
8
+ def up
9
+ return unless column_exists?(:settings, :category)
10
+
11
+ MigrationSettings.where(category: 'Setting::GitTemplates').update_all(category: 'Setting')
12
+ end
13
+ end
@@ -8,17 +8,24 @@ module ForemanGitTemplates
8
8
  config.autoload_paths += Dir["#{config.root}/app/services"]
9
9
  config.autoload_paths += Dir["#{config.root}/app/controllers/concerns"]
10
10
 
11
- initializer 'foreman_git_templates.load_default_settings', before: :load_config_initializers do
12
- require_dependency File.expand_path('../../app/models/setting/git_templates.rb', __dir__) if begin
13
- Setting.table_exists?
14
- rescue StandardError
15
- (false)
16
- end
11
+ initializer 'foreman_git_templates.load_app_instance_data' do |app|
12
+ ForemanGitTemplates::Engine.paths['db/migrate'].existent.each do |path|
13
+ app.config.paths['db/migrate'] << path
14
+ end
17
15
  end
18
16
 
19
17
  initializer 'foreman_git_templates.register_plugin', before: :finisher_hook do |_app|
20
18
  Foreman::Plugin.register :foreman_git_templates do
21
- requires_foreman '>= 1.20'
19
+ requires_foreman '>= 3.9'
20
+
21
+ settings do
22
+ category :git_templates, N_('Git Templates') do
23
+ setting :template_url_validation_timeout,
24
+ type: :integer,
25
+ default: 15,
26
+ description: _('Template URL validation timeout in seconds')
27
+ end
28
+ end
22
29
  end
23
30
  end
24
31
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ForemanGitTemplates
4
- VERSION = '1.0.5'
4
+ VERSION = '2.0.0'
5
5
  end
@@ -15,6 +15,3 @@ namespace :test do
15
15
  end
16
16
 
17
17
  Rake::Task[:test].enhance ['test:foreman_git_templates']
18
-
19
- load 'tasks/jenkins.rake'
20
- Rake::Task['jenkins:unit'].enhance ['test:foreman_git_templates'] if Rake::Task.task_defined?(:'jenkins:unit')
@@ -8,7 +8,7 @@ class HostsControllerTest < ActionController::TestCase
8
8
  describe '#templates' do
9
9
  it 'returns only templates that are defined in the archive' do
10
10
  Dir.mktmpdir do |dir|
11
- expected_kinds = ['PXEGrub', 'PXELinux', 'iPXE', 'PXEGrub2', 'provision']
11
+ expected_kinds = %w[PXEGrub PXELinux iPXE PXEGrub2 provision]
12
12
 
13
13
  stub_repository host.params['template_url'], "#{dir}/repo.tar.gz" do |tar|
14
14
  expected_kinds.each do |kind|
@@ -34,8 +34,12 @@ class UnattendedControllerTest < ActionController::TestCase
34
34
  template_content = "<%= snippet('#{snippet_name}', variables: { foo: 'bar' }) %>"
35
35
 
36
36
  stub_repository host.params['template_url'], "#{dir}/repo.tar.gz" do |tar|
37
- tar.add_file_simple("templates/#{kind}/template.erb", 644, template_content.length) { |io| io.write(template_content) }
38
- tar.add_file_simple("templates/snippets/#{snippet_name.downcase}.erb", 644, snippet_content.length) { |io| io.write(snippet_content) }
37
+ tar.add_file_simple("templates/#{kind}/template.erb", 644, template_content.length) do |io|
38
+ io.write(template_content)
39
+ end
40
+ tar.add_file_simple("templates/snippets/#{snippet_name.downcase}.erb", 644, snippet_content.length) do |io|
41
+ io.write(snippet_content)
42
+ end
39
43
  end
40
44
 
41
45
  get :host_template, params: { kind: kind, hostname: host.name }, session: set_session_user
@@ -58,20 +62,34 @@ class UnattendedControllerTest < ActionController::TestCase
58
62
  template_content = "<%= snippet('#{snippet_name}', variables: { foo: 'foo' }) %>"
59
63
 
60
64
  stub_repository host.params['template_url'], "#{dir}/repo.tar.gz" do |tar|
61
- tar.add_file_simple("templates/#{kind}/template.erb", 644, template_content.length) { |io| io.write(template_content) }
62
- tar.add_file_simple("templates/snippets/#{snippet_name.downcase}.erb", 644, snippet_content.length) { |io| io.write(snippet_content) }
63
- tar.add_file_simple("templates/snippets/#{nested_snippet_name.downcase}.erb", 644, nested_snippet_content.length) { |io| io.write(nested_snippet_content) }
65
+ tar.add_file_simple("templates/#{kind}/template.erb", 644, template_content.length) do |io|
66
+ io.write(template_content)
67
+ end
68
+ tar.add_file_simple("templates/snippets/#{snippet_name.downcase}.erb", 644, snippet_content.length) do |io|
69
+ io.write(snippet_content)
70
+ end
71
+ tar.add_file_simple("templates/snippets/#{nested_snippet_name.downcase}.erb", 644,
72
+ nested_snippet_content.length) do |io|
73
+ io.write(nested_snippet_content)
74
+ end
64
75
  end
65
76
 
66
77
  get :host_template, params: { kind: kind, hostname: host.name }, session: set_session_user
67
78
  assert_response :success
68
- assert_equal 'foo bar', response.body.strip
79
+ assert_equal 'foo foobar', response.body.strip
69
80
  end
70
81
  end
71
82
 
72
83
  describe 'iPXE templates' do
73
84
  let(:host) do
74
- FactoryBot.create(:host, :managed, :with_template_url, build: false, operatingsystem: os, ptable: os.ptables.first)
85
+ FactoryBot.create(
86
+ :host,
87
+ :managed,
88
+ :with_template_url,
89
+ build: false,
90
+ operatingsystem: os,
91
+ ptable: os.ptables.first
92
+ )
75
93
  end
76
94
 
77
95
  context 'host not in build mode' do
@@ -34,7 +34,7 @@ module Hostext
34
34
 
35
35
  test 'available_template_kinds finds only templates that are defined in the repository' do
36
36
  Dir.mktmpdir do |dir|
37
- expected_kinds = ['PXEGrub', 'PXELinux', 'iPXE', 'PXEGrub2', 'provision']
37
+ expected_kinds = %w[PXEGrub PXELinux iPXE PXEGrub2 provision]
38
38
 
39
39
  stub_repository host.params['template_url'], "#{dir}/repo.tar.gz" do |tar|
40
40
  expected_kinds.each do |kind|
@@ -14,7 +14,9 @@ class TFTPOrchestrationTest < ActiveSupport::TestCase
14
14
  it 'renders main template' do
15
15
  Dir.mktmpdir do |dir|
16
16
  stub_repository host.params['template_url'], "#{dir}/repo.tar.gz" do |tar|
17
- tar.add_file_simple("templates/#{kind}/template.erb", 644, template_content.length) { |io| io.write(template_content) }
17
+ tar.add_file_simple("templates/#{kind}/template.erb", 644, template_content.length) do |io|
18
+ io.write(template_content)
19
+ end
18
20
  end
19
21
 
20
22
  assert_equal template_content, host.generate_pxe_template(kind)
@@ -38,7 +40,10 @@ class TFTPOrchestrationTest < ActiveSupport::TestCase
38
40
  it 'renders default local boot template' do
39
41
  Dir.mktmpdir do |dir|
40
42
  stub_repository host.params['template_url'], "#{dir}/repo.tar.gz" do |tar|
41
- tar.add_file_simple("templates/#{kind}/default_local_boot.erb", 644, default_local_boot_template_content.length) { |io| io.write(default_local_boot_template_content) }
43
+ tar.add_file_simple("templates/#{kind}/default_local_boot.erb", 644,
44
+ default_local_boot_template_content.length) do |io|
45
+ io.write(default_local_boot_template_content)
46
+ end
42
47
  end
43
48
 
44
49
  assert_equal default_local_boot_template_content, host.generate_pxe_template(kind)
@@ -58,22 +63,29 @@ class TFTPOrchestrationTest < ActiveSupport::TestCase
58
63
  end
59
64
 
60
65
  describe '#validate_tftp' do
61
- let(:host) { FactoryBot.create(:host, :with_tftp_orchestration, :with_template_url, build: false, pxe_loader: 'PXELinux BIOS') }
66
+ let(:host) do
67
+ FactoryBot.create(:host, :with_tftp_orchestration, :with_template_url, build: false, pxe_loader: 'PXELinux BIOS')
68
+ end
62
69
  let(:kind) { 'PXELinux' }
63
70
  let(:template_content) { 'main template content' }
64
71
  let(:default_local_boot_template_content) { 'default local boot template content' }
65
72
 
66
73
  context 'host is in build mode' do
67
74
  setup do
68
- host.primary_interface.expects(:valid?).returns(true) if Gem::Version.new(SETTINGS[:version].notag) >= Gem::Version.new('2.0')
75
+ host.primary_interface.expects(:valid?).returns(true)
69
76
  host.update(build: true)
70
77
  end
71
78
 
72
79
  it 'validates that the host is ready for tftp' do
73
80
  Dir.mktmpdir do |dir|
74
81
  stub_repository host.params['template_url'], "#{dir}/repo.tar.gz" do |tar|
75
- tar.add_file_simple("templates/#{kind}/template.erb", 644, template_content.length) { |io| io.write(template_content) }
76
- tar.add_file_simple("templates/#{kind}/default_local_boot.erb", 644, default_local_boot_template_content.length) { |io| io.write(default_local_boot_template_content) }
82
+ tar.add_file_simple("templates/#{kind}/template.erb", 644, template_content.length) do |io|
83
+ io.write(template_content)
84
+ end
85
+ tar.add_file_simple("templates/#{kind}/default_local_boot.erb", 644,
86
+ default_local_boot_template_content.length) do |io|
87
+ io.write(default_local_boot_template_content)
88
+ end
77
89
  end
78
90
 
79
91
  host.provision_interface.send(:validate_tftp)
@@ -86,8 +98,13 @@ class TFTPOrchestrationTest < ActiveSupport::TestCase
86
98
  it 'validates that the host is ready for tftp' do
87
99
  Dir.mktmpdir do |dir|
88
100
  stub_repository host.params['template_url'], "#{dir}/repo.tar.gz" do |tar|
89
- tar.add_file_simple("templates/#{kind}/template.erb", 644, template_content.length) { |io| io.write(template_content) }
90
- tar.add_file_simple("templates/#{kind}/default_local_boot.erb", 644, default_local_boot_template_content.length) { |io| io.write(default_local_boot_template_content) }
101
+ tar.add_file_simple("templates/#{kind}/template.erb", 644, template_content.length) do |io|
102
+ io.write(template_content)
103
+ end
104
+ tar.add_file_simple("templates/#{kind}/default_local_boot.erb", 644,
105
+ default_local_boot_template_content.length) do |io|
106
+ io.write(default_local_boot_template_content)
107
+ end
91
108
  end
92
109
 
93
110
  host.provision_interface.send(:validate_tftp)
@@ -106,7 +123,7 @@ class TFTPOrchestrationTest < ActiveSupport::TestCase
106
123
 
107
124
  context 'host is in build mode' do
108
125
  setup do
109
- host.primary_interface.expects(:valid?).returns(true) if Gem::Version.new(SETTINGS[:version].notag) >= Gem::Version.new('2.0')
126
+ host.primary_interface.expects(:valid?).returns(true)
110
127
  host.update(build: true)
111
128
  end
112
129
 
@@ -115,11 +132,17 @@ class TFTPOrchestrationTest < ActiveSupport::TestCase
115
132
 
116
133
  Dir.mktmpdir do |dir|
117
134
  stub_repository host.params['template_url'], "#{dir}/repo.tar.gz" do |tar|
118
- tar.add_file_simple("templates/#{kind}/template.erb", 644, template_content.length) { |io| io.write(template_content) }
119
- tar.add_file_simple("templates/#{kind}/default_local_boot.erb", 644, default_local_boot_template_content.length) { |io| io.write(default_local_boot_template_content) }
135
+ tar.add_file_simple("templates/#{kind}/template.erb", 644, template_content.length) do |io|
136
+ io.write(template_content)
137
+ end
138
+ tar.add_file_simple("templates/#{kind}/default_local_boot.erb", 644,
139
+ default_local_boot_template_content.length) do |io|
140
+ io.write(default_local_boot_template_content)
141
+ end
120
142
  end
121
143
 
122
- ProxyAPI::TFTP.any_instance.expects(:set).with(kind, host.interfaces.first.mac, pxeconfig: template_content).once
144
+ ProxyAPI::TFTP.any_instance.expects(:set).with(kind, host.interfaces.first.mac,
145
+ pxeconfig: template_content).once
123
146
 
124
147
  host.provision_interface.send(:setTFTP, kind)
125
148
  end
@@ -136,11 +159,17 @@ class TFTPOrchestrationTest < ActiveSupport::TestCase
136
159
 
137
160
  Dir.mktmpdir do |dir|
138
161
  stub_repository host.params['template_url'], "#{dir}/repo.tar.gz" do |tar|
139
- tar.add_file_simple("templates/#{kind}/template.erb", 644, template_content.length) { |io| io.write(template_content) }
140
- tar.add_file_simple("templates/#{kind}/default_local_boot.erb", 644, default_local_boot_template_content.length) { |io| io.write(default_local_boot_template_content) }
162
+ tar.add_file_simple("templates/#{kind}/template.erb", 644, template_content.length) do |io|
163
+ io.write(template_content)
164
+ end
165
+ tar.add_file_simple("templates/#{kind}/default_local_boot.erb", 644,
166
+ default_local_boot_template_content.length) do |io|
167
+ io.write(default_local_boot_template_content)
168
+ end
141
169
  end
142
170
 
143
- ProxyAPI::TFTP.any_instance.expects(:set).with(kind, host.interfaces.first.mac, pxeconfig: default_local_boot_template_content).once
171
+ ProxyAPI::TFTP.any_instance.expects(:set).with(kind, host.interfaces.first.mac,
172
+ pxeconfig: default_local_boot_template_content).once
144
173
 
145
174
  host.provision_interface.send(:setTFTP, kind)
146
175
  end
@@ -21,7 +21,7 @@ module ForemanGitTemplates
21
21
  it 'is invlid' do
22
22
  stub_request(:head, template_url).to_return(status: 401)
23
23
 
24
- assert_equal false, host_parameter.valid?
24
+ assert_not host_parameter.valid?
25
25
  assert_not_empty host_parameter.errors[:value]
26
26
  end
27
27
  end
@@ -30,7 +30,7 @@ module ForemanGitTemplates
30
30
  it 'is invlid' do
31
31
  stub_request(:head, template_url).to_return(status: 404)
32
32
 
33
- assert_equal false, host_parameter.valid?
33
+ assert_not host_parameter.valid?
34
34
  assert_not_empty host_parameter.errors[:value]
35
35
  end
36
36
  end
@@ -39,7 +39,7 @@ module ForemanGitTemplates
39
39
  it 'is invlid' do
40
40
  stub_request(:head, template_url).to_return(status: 500)
41
41
 
42
- assert_equal false, host_parameter.valid?
42
+ assert_not host_parameter.valid?
43
43
  assert_not_empty host_parameter.errors[:value]
44
44
  end
45
45
  end
@@ -48,7 +48,7 @@ module ForemanGitTemplates
48
48
  let(:template_url) { 'not URL value' }
49
49
 
50
50
  it 'is invlid' do
51
- assert_equal false, host_parameter.valid?
51
+ assert_not host_parameter.valid?
52
52
  assert_not_empty host_parameter.errors[:value]
53
53
  end
54
54
  end
@@ -28,6 +28,17 @@ module ForemanGitTemplates
28
28
 
29
29
  describe '#update' do
30
30
  let(:os) { FactoryBot.create(:operatingsystem, :with_associations, type: 'Redhat') }
31
+ let(:fake_response) do
32
+ {
33
+ 'name' => 'www.example.com',
34
+ 'mac' => '00:11:22:33:44:55',
35
+ 'ip' => '192.168.0.10',
36
+ 'filename' => 'pxelinux.0',
37
+ 'nextServer' => '1.2.3.4',
38
+ 'hostname' => 'www.example.com',
39
+ 'subnet' => '192.168.0.0/255.255.255.0',
40
+ }
41
+ end
31
42
 
32
43
  setup do
33
44
  host.expects(:skip_orchestration_for_testing?).at_least_once.returns(false)
@@ -37,24 +48,35 @@ module ForemanGitTemplates
37
48
  setup do
38
49
  ProxyAPI::TFTP.any_instance.expects(:set).returns(true)
39
50
 
40
- if Gem::Version.new(SETTINGS[:version].notag) >= Gem::Version.new('2.0')
41
- ProxyAPI::TFTP.any_instance.expects(:bootServer).returns('127.0.0.1')
42
- ProxyAPI::DHCP.any_instance.expects(:set).returns(true)
43
- ProxyAPI::DHCP.any_instance.expects(:record).with(host.subnet.network, host.dhcp_records.first.mac).returns(host.dhcp_records.first)
44
- ProxyAPI::DHCP.any_instance.expects(:records_by_ip).with(host.subnet.network, host.provision_interface.ip).returns([host.dhcp_records.first])
45
- ProxyAPI::DHCP.any_instance.expects(:delete).returns(true)
46
- end
51
+ stub_request(:get, %r{https://.*:8443/tftp/serverName})
52
+ .to_return(status: 200, body: 'server.com')
53
+
54
+ stub_request(:get, %r{.+://.+/dhcp/[0-9.]{7,15}/mac/([0-9a-f]{2}:){5}[0-9a-f]{2}})
55
+ .to_return(status: 200, body: fake_rest_client_response(fake_response))
56
+
57
+ ProxyAPI::TFTP.any_instance.expects(:bootServer).returns('127.0.0.1').twice
58
+
59
+ ProxyAPI::DHCP.any_instance.expects(:records_by_ip).with(host.subnet.network,
60
+ host.provision_interface.ip).returns([host.dhcp_records.first])
61
+ ProxyAPI::DHCP.any_instance.expects(:delete).returns(true)
62
+ ProxyAPI::DHCP.any_instance.expects(:record).with(host.subnet.network,
63
+ host.dhcp_records.first.mac).returns(host.dhcp_records.first)
64
+ ProxyAPI::DHCP.any_instance.expects(:set).returns(true)
47
65
  end
48
66
 
49
67
  context 'when host is in build mode' do
50
- let(:host) { FactoryBot.create(:host, :with_tftp_orchestration, :with_template_url, operatingsystem: os, build: true) }
68
+ let(:host) do
69
+ FactoryBot.create(:host, :with_tftp_orchestration, :with_template_url, operatingsystem: os, build: true)
70
+ end
51
71
 
52
72
  it 'updates the host' do
53
73
  ProxyAPI::TFTP.any_instance.expects(:fetch_boot_file).twice.returns(true)
54
74
 
55
75
  Dir.mktmpdir do |dir|
56
76
  stub_repository host.params['template_url'], "#{dir}/repo.tar.gz" do |tar|
57
- tar.add_file_simple('templates/PXEGrub2/template.erb', 644, host.name.length) { |io| io.write(host.name) }
77
+ tar.add_file_simple('templates/PXEGrub2/template.erb', 644, host.name.length) do |io|
78
+ io.write(host.name)
79
+ end
58
80
  end
59
81
 
60
82
  assert host.update(name: 'newname')
@@ -64,12 +86,16 @@ module ForemanGitTemplates
64
86
  end
65
87
 
66
88
  context 'when host is not in build mode' do
67
- let(:host) { FactoryBot.create(:host, :with_tftp_orchestration, :with_template_url, operatingsystem: os, build: false) }
89
+ let(:host) do
90
+ FactoryBot.create(:host, :with_tftp_orchestration, :with_template_url, operatingsystem: os, build: false)
91
+ end
68
92
 
69
93
  it 'updates the host' do
70
94
  Dir.mktmpdir do |dir|
71
95
  stub_repository host.params['template_url'], "#{dir}/repo.tar.gz" do |tar|
72
- tar.add_file_simple('templates/PXEGrub2/default_local_boot.erb', 644, host.name.length) { |io| io.write(host.name) }
96
+ tar.add_file_simple('templates/PXEGrub2/default_local_boot.erb', 644, host.name.length) do |io|
97
+ io.write(host.name)
98
+ end
73
99
  end
74
100
 
75
101
  assert host.update(name: 'newname')
@@ -83,30 +109,36 @@ module ForemanGitTemplates
83
109
  setup do
84
110
  stub_request(:get, host.params['template_url']).to_return(status: 404)
85
111
 
86
- if Gem::Version.new(SETTINGS[:version].notag) >= Gem::Version.new('2.0')
87
- ProxyAPI::TFTP.any_instance.expects(:bootServer).returns('127.0.0.1')
88
- ProxyAPI::DHCP.any_instance.expects(:record).with(host.subnet.network, host.dhcp_records.first.mac).returns(host.dhcp_records.first)
89
- ProxyAPI::DHCP.any_instance.expects(:records_by_ip).with(host.subnet.network, host.provision_interface.ip).returns([host.dhcp_records.first])
90
- end
112
+ ProxyAPI::TFTP.any_instance.expects(:bootServer).returns('127.0.0.1').twice
113
+ ProxyAPI::DHCP.any_instance.expects(:record).with(host.subnet.network,
114
+ host.dhcp_records.first.mac).returns(host.dhcp_records.first)
115
+ ProxyAPI::DHCP.any_instance.expects(:records_by_ip).with(host.subnet.network,
116
+ host.provision_interface.ip).returns([host.dhcp_records.first])
91
117
  end
92
118
 
93
- let(:expected_errors) { ["No PXEGrub2 template was found for host #{host.name}. Repository url: #{host.params['template_url']}"] }
119
+ let(:expected_errors) do
120
+ ["No PXEGrub2 template was found for host #{host.name}. Repository url: #{host.params['template_url']}"]
121
+ end
94
122
 
95
123
  context 'when host is in build mode' do
96
- let(:host) { FactoryBot.create(:host, :with_tftp_orchestration, :with_template_url, operatingsystem: os, build: true) }
124
+ let(:host) do
125
+ FactoryBot.create(:host, :with_tftp_orchestration, :with_template_url, operatingsystem: os, build: true)
126
+ end
97
127
 
98
128
  it 'does not update the host' do
99
- assert_equal false, host.update(name: 'newname')
129
+ assert_not host.update(name: 'newname')
100
130
  assert_equal expected_errors, host.errors[:base]
101
131
  assert_equal expected_errors, host.errors[:'interfaces.base']
102
132
  end
103
133
  end
104
134
 
105
135
  context 'when host is not in build mode' do
106
- let(:host) { FactoryBot.create(:host, :with_tftp_orchestration, :with_template_url, operatingsystem: os, build: false) }
136
+ let(:host) do
137
+ FactoryBot.create(:host, :with_tftp_orchestration, :with_template_url, operatingsystem: os, build: false)
138
+ end
107
139
 
108
140
  it 'does not update the host' do
109
- assert_equal false, host.update(name: 'newname')
141
+ assert_not host.update(name: 'newname')
110
142
  assert_equal expected_errors, host.errors[:base]
111
143
  assert_equal expected_errors, host.errors[:'interfaces.base']
112
144
  end
@@ -4,7 +4,9 @@ require 'test_plugin_helper'
4
4
 
5
5
  module ForemanGitTemplates
6
6
  class SnippetRepositoryTest < ActiveSupport::TestCase
7
- let(:snippet_repository_template) { ForemanGitTemplates::SnippetRepositoryTemplate.new(name: 'CoreOS provision Ignition') }
7
+ let(:snippet_repository_template) do
8
+ ForemanGitTemplates::SnippetRepositoryTemplate.new(name: 'CoreOS provision Ignition')
9
+ end
8
10
 
9
11
  test '#path downcases the filename and replaces spaces with underscores' do
10
12
  assert_equal 'templates/snippets/coreos_provision_ignition.erb', snippet_repository_template.path
@@ -22,7 +22,7 @@ class RepositorySourceTest < ActiveSupport::TestCase
22
22
 
23
23
  test 'should return snippet template' do
24
24
  assert snippet.is_a?(ForemanGitTemplates::SnippetRepositoryTemplate)
25
- assert snippet.respond_to?(:render)
25
+ assert_respond_to snippet, :render
26
26
  assert_equal snippet_name, snippet.name
27
27
  end
28
28
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_plugin_helper'
4
+ require 'unit/shared/access_permissions_test_base'
5
+
6
+ # Permissions are added in AccessPermissions with lists of controllers and
7
+ # actions that they enable access to. For non-admin users, we need to test
8
+ # that there are permissions available that cover every controller action, else
9
+ # it can't be delegated and this will lead to parts of the application that
10
+ # aren't functional for non-admin users.
11
+ #
12
+ # In particular, it's important that actions for AJAX requests are added to
13
+ # an appropriate permission so views using those requests function.
14
+ class AccessPermissionsTest < ActiveSupport::TestCase
15
+ include AccessPermissionsTestBase
16
+
17
+ check_routes(ForemanGitTemplates::Engine.routes, [])
18
+ end
@@ -29,7 +29,11 @@ class RepositoryFetcherTest < ActiveSupport::TestCase
29
29
  test 'should raise RepositoryFetcherError when url is incorrect' do
30
30
  url = 'incorrect_url'
31
31
 
32
- msg = 'URL scheme needs to be http or https'
32
+ # "rest-client" normalizes a URL by adding a protocol if none is present
33
+ requested_url = "http://#{url}"
34
+ stub_request(:get, requested_url).to_return(status: 404)
35
+
36
+ msg = 'Response code: 404'
33
37
  assert_raises_with_message(ForemanGitTemplates::RepositoryFetcher::RepositoryFetcherError, msg) do
34
38
  ForemanGitTemplates::RepositoryFetcher.call(url)
35
39
  end
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_git_templates
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.5
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - dmTECH GmbH
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-10 00:00:00.000000000 Z
11
+ date: 2024-05-14 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: down
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '4.5'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '4.5'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: rest-client
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -53,33 +39,19 @@ dependencies:
53
39
  - !ruby/object:Gem::Version
54
40
  version: '0'
55
41
  - !ruby/object:Gem::Dependency
56
- name: rubocop
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: rubocop-rails
42
+ name: theforeman-rubocop
71
43
  requirement: !ruby/object:Gem::Requirement
72
44
  requirements:
73
- - - ">="
45
+ - - "~>"
74
46
  - !ruby/object:Gem::Version
75
- version: '0'
47
+ version: 0.1.2
76
48
  type: :development
77
49
  prerelease: false
78
50
  version_requirements: !ruby/object:Gem::Requirement
79
51
  requirements:
80
- - - ">="
52
+ - - "~>"
81
53
  - !ruby/object:Gem::Version
82
- version: '0'
54
+ version: 0.1.2
83
55
  description:
84
56
  email:
85
57
  - opensource@dm.de
@@ -103,10 +75,10 @@ files:
103
75
  - app/models/foreman_git_templates/default_local_boot_repository_template.rb
104
76
  - app/models/foreman_git_templates/main_repository_template.rb
105
77
  - app/models/foreman_git_templates/snippet_repository_template.rb
106
- - app/models/setting/git_templates.rb
107
78
  - app/services/foreman_git_templates/repository_fetcher.rb
108
79
  - app/services/foreman_git_templates/repository_reader.rb
109
80
  - config/routes.rb
81
+ - db/migrate/20230203130941_fix_git_templates_settings_category_to_dsl.rb
110
82
  - lib/foreman_git_templates.rb
111
83
  - lib/foreman_git_templates/engine.rb
112
84
  - lib/foreman_git_templates/version.rb
@@ -122,6 +94,7 @@ files:
122
94
  - test/test_plugin_helper.rb
123
95
  - test/unit/foreman/renderer/source/repository_test.rb
124
96
  - test/unit/foreman/renderer_test.rb
97
+ - test/unit/foreman_git_templates/access_permissions_test.rb
125
98
  - test/unit/repository_fetcher_test.rb
126
99
  - test/unit/repository_reader_test.rb
127
100
  homepage: https://github.com/dm-drogeriemarkt/foreman_git_templates
@@ -136,28 +109,32 @@ required_ruby_version: !ruby/object:Gem::Requirement
136
109
  requirements:
137
110
  - - ">="
138
111
  - !ruby/object:Gem::Version
139
- version: '0'
112
+ version: '2.5'
113
+ - - "<"
114
+ - !ruby/object:Gem::Version
115
+ version: '4'
140
116
  required_rubygems_version: !ruby/object:Gem::Requirement
141
117
  requirements:
142
118
  - - ">="
143
119
  - !ruby/object:Gem::Version
144
120
  version: '0'
145
121
  requirements: []
146
- rubygems_version: 3.1.2
122
+ rubygems_version: 3.4.1
147
123
  signing_key:
148
124
  specification_version: 4
149
125
  summary: Adds support for using templates from Git repositories
150
126
  test_files:
151
- - test/unit/repository_fetcher_test.rb
152
- - test/unit/foreman/renderer/source/repository_test.rb
153
- - test/unit/foreman/renderer_test.rb
154
- - test/unit/repository_reader_test.rb
155
- - test/models/foreman_git_templates/snippet_repository_template_test.rb
156
- - test/models/foreman_git_templates/host_test.rb
157
- - test/models/foreman_git_templates/host_parameter_test.rb
127
+ - test/controllers/hosts_controller_test.rb
128
+ - test/controllers/unattended_controller_test.rb
129
+ - test/factories/foreman_git_templates_factories.rb
158
130
  - test/models/concerns/foreman_git_templates/hostext/operating_system_test.rb
159
131
  - test/models/concerns/foreman_git_templates/orchestration/tftp_test.rb
160
- - test/factories/foreman_git_templates_factories.rb
132
+ - test/models/foreman_git_templates/host_parameter_test.rb
133
+ - test/models/foreman_git_templates/host_test.rb
134
+ - test/models/foreman_git_templates/snippet_repository_template_test.rb
161
135
  - test/test_plugin_helper.rb
162
- - test/controllers/unattended_controller_test.rb
163
- - test/controllers/hosts_controller_test.rb
136
+ - test/unit/foreman/renderer/source/repository_test.rb
137
+ - test/unit/foreman/renderer_test.rb
138
+ - test/unit/foreman_git_templates/access_permissions_test.rb
139
+ - test/unit/repository_fetcher_test.rb
140
+ - test/unit/repository_reader_test.rb
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Setting
4
- class GitTemplates < ::Setting
5
- def self.default_settings
6
- [
7
- set('template_url_validation_timeout', N_('Template URL validation timeout in seconds'), 15, N_('Template URL validation timeout'))
8
- ]
9
- end
10
-
11
- def self.load_defaults
12
- # Check the table exists
13
- return unless super
14
-
15
- transaction do
16
- default_settings.each { |s| create! s.update(category: 'Setting::GitTemplates') }
17
- end
18
-
19
- true
20
- end
21
-
22
- def self.humanized_category
23
- N_('GitTemplates')
24
- end
25
- end
26
- end