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.
- checksums.yaml +4 -4
- data/README.md +1 -0
- data/Rakefile +4 -2
- data/app/controllers/concerns/foreman_git_templates/unattended_controller_extensions.rb +1 -1
- data/app/lib/foreman_git_templates/renderer/source/repository.rb +2 -1
- data/app/lib/foreman_git_templates/renderer.rb +1 -5
- data/app/models/concerns/foreman_git_templates/host_parameter_extensions.rb +2 -2
- data/app/models/concerns/foreman_git_templates/orchestration/tftp.rb +12 -2
- data/app/services/foreman_git_templates/repository_fetcher.rb +4 -4
- data/app/services/foreman_git_templates/repository_reader.rb +8 -1
- data/db/migrate/20230203130941_fix_git_templates_settings_category_to_dsl.rb +13 -0
- data/lib/foreman_git_templates/engine.rb +14 -7
- data/lib/foreman_git_templates/version.rb +1 -1
- data/lib/tasks/foreman_git_templates_tasks.rake +0 -3
- data/test/controllers/hosts_controller_test.rb +1 -1
- data/test/controllers/unattended_controller_test.rb +25 -7
- data/test/models/concerns/foreman_git_templates/hostext/operating_system_test.rb +1 -1
- data/test/models/concerns/foreman_git_templates/orchestration/tftp_test.rb +44 -15
- data/test/models/foreman_git_templates/host_parameter_test.rb +4 -4
- data/test/models/foreman_git_templates/host_test.rb +53 -21
- data/test/models/foreman_git_templates/snippet_repository_template_test.rb +3 -1
- data/test/unit/foreman/renderer/source/repository_test.rb +1 -1
- data/test/unit/foreman_git_templates/access_permissions_test.rb +18 -0
- data/test/unit/repository_fetcher_test.rb +5 -1
- metadata +25 -48
- data/app/models/setting/git_templates.rb +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a94d6d6381bf398d3f036ca2fb9fed20c9868140ab53e116d76805e0bee2d30b
|
4
|
+
data.tar.gz: 0b7a8fd7ae5d564da6be772161c8f7a4480102d5a950ac573560060eb44f08ea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cba39a64316baa32786d262f0e94aa173ef164c9325a69b9e698bd6b698ffa9d89bfe7a08353fa259cb044041586b04a112fd5c87acf47a9b838e5dd5903a6f6
|
7
|
+
data.tar.gz: e60a95dd0e3ab7da8cdba0752515eb6c324a909779363f492f0d16807fb2432d26f0562957d64ebd8b02ae115969e14ea9fc722ac680f09d0de5cdbd3f392e3a
|
data/README.md
CHANGED
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('
|
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
|
-
|
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
|
-
|
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
|
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
|
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
|
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
|
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 '
|
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
|
-
|
13
|
-
rescue
|
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
|
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,
|
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.
|
12
|
-
|
13
|
-
|
14
|
-
|
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 '>=
|
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
|
|
@@ -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 = [
|
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)
|
38
|
-
|
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)
|
62
|
-
|
63
|
-
|
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
|
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(
|
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 = [
|
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)
|
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,
|
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)
|
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)
|
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)
|
76
|
-
|
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)
|
90
|
-
|
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)
|
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)
|
119
|
-
|
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,
|
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)
|
140
|
-
|
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,
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
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)
|
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)
|
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)
|
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)
|
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
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
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)
|
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)
|
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
|
-
|
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)
|
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
|
-
|
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)
|
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
|
-
|
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
|
-
|
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:
|
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:
|
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:
|
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:
|
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: '
|
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
|
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/
|
152
|
-
- test/
|
153
|
-
- test/
|
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/
|
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/
|
163
|
-
- test/
|
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
|