foreman_git_templates 1.0.6 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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 -3
  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 +4 -1
  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 +23 -46
  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: 030b1cb7373a31b3b7a72326668906b00d523c5c92a0a62e41d2467570aa9d8e
4
- data.tar.gz: 0b27bc9ebb34b8b288234b366a6d1ac431eb0413d883e08ba605a9d419f2660a
3
+ metadata.gz: a94d6d6381bf398d3f036ca2fb9fed20c9868140ab53e116d76805e0bee2d30b
4
+ data.tar.gz: 0b7a8fd7ae5d564da6be772161c8f7a4480102d5a950ac573560060eb44f08ea
5
5
  SHA512:
6
- metadata.gz: b1fcc6b0035e91332f0600389db9445ca00c201c534ec19c26e2b55e0f2e33f23df73d0904b0256bdd81b7cf8b77903a3c17480aeb47174931c70efe11065b3e
7
- data.tar.gz: 6ef071e866eeca0076167ab6f04a780cd3b4c46b88bec95cb241a8fb91cc193e64e01aafd65c79d5c813ed59480f742a836675be62a50eb0621318db026e773d
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,14 +4,12 @@ module ForemanGitTemplates
4
4
  module Renderer
5
5
  REPOSITORY_SOURCE_CLASS = ForemanGitTemplates::Renderer::Source::Repository
6
6
 
7
- def get_source(klass: nil, template:, **args)
7
+ def get_source(template:, klass: nil, **args)
8
8
  return super if klass && klass != REPOSITORY_SOURCE_CLASS
9
9
 
10
10
  repository_path = repository_path(args[:host])
11
11
  if repository_path
12
12
  REPOSITORY_SOURCE_CLASS.new(template, repository_path)
13
- elsif !repository_path && Gem::Version.new(SETTINGS[:version].version) < Gem::Version.new('1.23')
14
- super(klass: klass || Foreman::Renderer::Source::Database, template: template, **args)
15
13
  else
16
14
  super
17
15
  end
@@ -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,6 +19,7 @@ module ForemanGitTemplates
19
19
 
20
20
  private
21
21
 
22
+ # rubocop:todo Metrics/AbcSize
22
23
  def validate_tftp
23
24
  return super unless feasible_for_git_template_rendering?
24
25
  return unless tftp? || tftp6?
@@ -27,8 +28,10 @@ module ForemanGitTemplates
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'])
31
33
  end
34
+ # rubocop:enable Metrics/AbcSize
32
35
 
33
36
  def feasible_for_git_template_rendering?
34
37
  return false unless host.is_a?(Host::Managed)
@@ -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.6'
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.6
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-08-13 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
42
+ name: theforeman-rubocop
57
43
  requirement: !ruby/object:Gem::Requirement
58
44
  requirements:
59
45
  - - "~>"
60
46
  - !ruby/object:Gem::Version
61
- version: 0.89.0
47
+ version: 0.1.2
62
48
  type: :development
63
49
  prerelease: false
64
50
  version_requirements: !ruby/object:Gem::Requirement
65
51
  requirements:
66
52
  - - "~>"
67
53
  - !ruby/object:Gem::Version
68
- version: 0.89.0
69
- - !ruby/object:Gem::Dependency
70
- name: rubocop-rails
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !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