foreman_bootdisk 17.0.2 → 19.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -3
  3. data/app/controllers/concerns/allowed_actions.rb +16 -0
  4. data/app/controllers/foreman_bootdisk/api/v2/disks_controller.rb +11 -2
  5. data/app/controllers/foreman_bootdisk/api/v2/subnet_disks_controller.rb +7 -0
  6. data/app/controllers/foreman_bootdisk/disks_controller.rb +71 -19
  7. data/app/controllers/foreman_bootdisk/subnet_disks_controller.rb +41 -0
  8. data/app/helpers/bootdisk_links_helper.rb +46 -0
  9. data/app/helpers/concerns/foreman_bootdisk/hosts_helper_ext.rb +57 -43
  10. data/app/helpers/concerns/foreman_bootdisk/pretty_error.rb +13 -0
  11. data/app/helpers/concerns/foreman_bootdisk/subnets_helper_ext.rb +45 -0
  12. data/app/helpers/disk_helper.rb +8 -0
  13. data/app/lib/foreman_bootdisk/scope/bootdisk.rb +24 -0
  14. data/app/models/concerns/foreman_bootdisk/host_ext.rb +6 -0
  15. data/app/models/concerns/foreman_bootdisk/orchestration/compute.rb +10 -3
  16. data/app/models/setting/bootdisk.rb +10 -1
  17. data/app/services/foreman_bootdisk/iso_generator.rb +23 -5
  18. data/app/views/foreman_bootdisk/disks/help.html.erb +16 -4
  19. data/app/views/foreman_bootdisk/generic_efi_host.erb +4 -0
  20. data/app/views/foreman_bootdisk/host.erb +7 -0
  21. data/app/views/subnets/_bootdisk_action_buttons.erb +1 -0
  22. data/app/views/subnets/_bootdisk_title_buttons.erb +1 -0
  23. data/config/routes.rb +2 -1
  24. data/db/migrate/20140522185700_change_templatekind_to_bootdisk.rb +3 -11
  25. data/lib/foreman_bootdisk/engine.rb +14 -2
  26. data/lib/foreman_bootdisk/version.rb +1 -1
  27. data/lib/tasks/bootdisk.rake +1 -19
  28. data/locale/action_names.rb +1 -1
  29. data/locale/ca/LC_MESSAGES/foreman_bootdisk.mo +0 -0
  30. data/locale/ca/foreman_bootdisk.edit.po +393 -0
  31. data/locale/ca/foreman_bootdisk.po +47 -11
  32. data/locale/ca/foreman_bootdisk.po.time_stamp +0 -0
  33. data/locale/de/LC_MESSAGES/foreman_bootdisk.mo +0 -0
  34. data/locale/de/foreman_bootdisk.edit.po +398 -0
  35. data/locale/de/foreman_bootdisk.po +63 -26
  36. data/locale/de/foreman_bootdisk.po.time_stamp +0 -0
  37. data/locale/en/LC_MESSAGES/foreman_bootdisk.mo +0 -0
  38. data/locale/en/foreman_bootdisk.edit.po +388 -0
  39. data/locale/en/foreman_bootdisk.po +45 -9
  40. data/locale/en/foreman_bootdisk.po.time_stamp +0 -0
  41. data/locale/en_GB/LC_MESSAGES/foreman_bootdisk.mo +0 -0
  42. data/locale/en_GB/foreman_bootdisk.edit.po +394 -0
  43. data/locale/en_GB/foreman_bootdisk.po +47 -11
  44. data/locale/en_GB/foreman_bootdisk.po.time_stamp +0 -0
  45. data/locale/es/LC_MESSAGES/foreman_bootdisk.mo +0 -0
  46. data/locale/es/foreman_bootdisk.edit.po +394 -0
  47. data/locale/es/foreman_bootdisk.po +69 -32
  48. data/locale/es/foreman_bootdisk.po.time_stamp +0 -0
  49. data/locale/foreman_bootdisk.pot +121 -63
  50. data/locale/fr/LC_MESSAGES/foreman_bootdisk.mo +0 -0
  51. data/locale/fr/foreman_bootdisk.edit.po +394 -0
  52. data/locale/fr/foreman_bootdisk.po +80 -43
  53. data/locale/fr/foreman_bootdisk.po.time_stamp +0 -0
  54. data/locale/it/LC_MESSAGES/foreman_bootdisk.mo +0 -0
  55. data/locale/it/foreman_bootdisk.edit.po +391 -0
  56. data/locale/it/foreman_bootdisk.po +47 -11
  57. data/locale/it/foreman_bootdisk.po.time_stamp +0 -0
  58. data/locale/ja/LC_MESSAGES/foreman_bootdisk.mo +0 -0
  59. data/locale/ja/foreman_bootdisk.edit.po +393 -0
  60. data/locale/ja/foreman_bootdisk.po +70 -33
  61. data/locale/ja/foreman_bootdisk.po.time_stamp +0 -0
  62. data/locale/ko/LC_MESSAGES/foreman_bootdisk.mo +0 -0
  63. data/locale/ko/foreman_bootdisk.edit.po +390 -0
  64. data/locale/ko/foreman_bootdisk.po +47 -11
  65. data/locale/ko/foreman_bootdisk.po.time_stamp +0 -0
  66. data/locale/pt_BR/LC_MESSAGES/foreman_bootdisk.mo +0 -0
  67. data/locale/pt_BR/foreman_bootdisk.edit.po +394 -0
  68. data/locale/pt_BR/foreman_bootdisk.po +79 -43
  69. data/locale/pt_BR/foreman_bootdisk.po.time_stamp +0 -0
  70. data/locale/ru/LC_MESSAGES/foreman_bootdisk.mo +0 -0
  71. data/locale/ru/foreman_bootdisk.edit.po +395 -0
  72. data/locale/ru/foreman_bootdisk.po +47 -11
  73. data/locale/ru/foreman_bootdisk.po.time_stamp +0 -0
  74. data/locale/sv_SE/LC_MESSAGES/foreman_bootdisk.mo +0 -0
  75. data/locale/sv_SE/foreman_bootdisk.edit.po +392 -0
  76. data/locale/sv_SE/foreman_bootdisk.po +47 -11
  77. data/locale/sv_SE/foreman_bootdisk.po.time_stamp +0 -0
  78. data/locale/zh_CN/LC_MESSAGES/foreman_bootdisk.mo +0 -0
  79. data/locale/zh_CN/foreman_bootdisk.edit.po +391 -0
  80. data/locale/zh_CN/foreman_bootdisk.po +113 -77
  81. data/locale/zh_CN/foreman_bootdisk.po.time_stamp +0 -0
  82. data/locale/zh_TW/LC_MESSAGES/foreman_bootdisk.mo +0 -0
  83. data/locale/zh_TW/foreman_bootdisk.edit.po +391 -0
  84. data/locale/zh_TW/foreman_bootdisk.po +47 -11
  85. data/locale/zh_TW/foreman_bootdisk.po.time_stamp +0 -0
  86. data/package.json +42 -0
  87. data/webpack/__mocks__/foremanReact/common/HOC.js +30 -0
  88. data/webpack/__mocks__/foremanReact/common/I18n.js +7 -0
  89. data/webpack/__mocks__/foremanReact/common/helpers.js +7 -0
  90. data/webpack/__mocks__/foremanReact/common/urlHelpers.js +8 -0
  91. data/webpack/__mocks__/foremanReact/constants.js +24 -0
  92. data/webpack/__mocks__/foremanReact/redux/API/APISelectors.js +6 -0
  93. data/webpack/__mocks__/foremanReact/redux/API/index.js +10 -0
  94. data/webpack/global_index.js +12 -0
  95. data/webpack/global_test_setup.js +11 -0
  96. data/webpack/index.js +0 -0
  97. data/webpack/src/extensions/constants.js +2 -0
  98. data/webpack/src/extensions/host/HostBootdiskButtons.js +71 -0
  99. data/webpack/src/extensions/host/HostBootdiskButtonsSelectors.js +27 -0
  100. data/webpack/src/extensions/host/__tests__/HostBootdiskButtonsSelectors.test.js +66 -0
  101. data/webpack/src/extensions/host/__tests__/__snapshots__/HostBootdiskButtonsSelectors.test.js.snap +30 -0
  102. metadata +60 -66
  103. data/.tx/config +0 -8
  104. data/AUTHORS +0 -30
  105. data/release-gem +0 -84
  106. data/test/functional/foreman_bootdisk/api/v2/disks_controller_test.rb +0 -97
  107. data/test/functional/foreman_bootdisk/api/v2/subnet_disks_controller_test.rb +0 -37
  108. data/test/functional/foreman_bootdisk/disks_controller_test.rb +0 -107
  109. data/test/models/host/managed_test.rb +0 -26
  110. data/test/test_plugin_helper.rb +0 -72
  111. data/test/unit/access_permissions_test.rb +0 -10
  112. data/test/unit/concerns/compute_resources/vmware_test.rb +0 -83
  113. data/test/unit/concerns/host_test.rb +0 -84
  114. data/test/unit/concerns/orchestration/compute_test.rb +0 -69
  115. data/test/unit/foreman_bootdisk/renderer_test.rb +0 -36
  116. data/test/unit/foreman_bootdisk/scope/bootdisk_test.rb +0 -31
  117. data/test/unit/foreman_bootdisk/scope/full_host_bootdisk_test.rb +0 -30
  118. data/test/unit/iso_generator_test.rb +0 -74
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cc43113465fd89f890f9606fb04af3e948b96ac1bd6c1943211a452e38c4cb2a
4
- data.tar.gz: 9db1069085f706df776576fc0df25f49a7d09ae71555ea15397d57656ddd0da5
3
+ metadata.gz: d21663a31369d139b9bac432999214fbcdb8d0cab69e3fba545c8dde84534fab
4
+ data.tar.gz: 7ab0ae10f8f2b2bf3826185251c6b7abaf6588c2a076ed0263b218a6a2780313
5
5
  SHA512:
6
- metadata.gz: 115bddba362f7c53b78d06ca78a1f120babae76cc2f922447cd0e05b1f322f189e30b186e6cb0718b7d9a24bfca67bf2287283fd9495eba4193a9b6bb560ec29
7
- data.tar.gz: 1cd764fdc0a939d45934070d6b34e2619870c8c206afd4915cae93f68f7553cfcc9b18d3c04770aba9f4b6f45d62bbd779563798b7175595ee8c2b991f03b660
6
+ metadata.gz: ad56a6d4126ecd913dc9b1938b1995427ce26d67377457281301ec73b4deab28e5241dbfffb5b6f2233c768cd3eb465c12ab990129c430de85350962a37ec309
7
+ data.tar.gz: a8da031331b090a898f6b9fde9e37bcb4b8bfed1a5b6e5e1f876b8595f872aa0ec64278cbc7d799ee09466f81c2236e94f126b9347f6c0d925a5ea7501ca821a
data/README.md CHANGED
@@ -228,7 +228,7 @@ The installation can continue on either the DHCP or static IP depending on how
228
228
  the OS iPXE template is configured, and could configure the assigned IP
229
229
  address statically for the installed system via the kickstart file.
230
230
 
231
- To generate the image from the web interface, view a host page, click the
231
+ To generate the image from the web interface, view a subnet page, click the
232
232
  "Boot disk" button and select "Generic image".
233
233
 
234
234
  To generate using the Hammer CLI, install the [hammer_cli_foreman_bootdisk](https://github.com/theforeman/hammer_cli_foreman_bootdisk)
@@ -269,8 +269,7 @@ the "Templates" module enabled and configured.
269
269
 
270
270
  This image is generic for all hosts with a provisioning NIC on that subnet.
271
271
 
272
- To generate the image from the web interface, view a host page, click the
273
- "Boot disk" button and select "Subnet image".
272
+ To generate the image from the web interface, view a subnet page and select "Subnet image" from subnet action buttons.
274
273
 
275
274
  To generate using the Hammer CLI, install the [hammer_cli_foreman_bootdisk](https://github.com/theforeman/hammer_cli_foreman_bootdisk)
276
275
  plugin and run:
@@ -0,0 +1,16 @@
1
+ module AllowedActions
2
+ extend ActiveSupport::Concern
3
+
4
+ def bootdisk_type_allowed?(action = params[:action])
5
+ return true if Setting::Bootdisk.allowed_types&.include?(action)
6
+
7
+ message = _('This type of bootdisk is not allowed. Please contact administrator.')
8
+ if api_request?
9
+ render_error :custom_error, status: :unprocessable_entity, locals: { message: message}
10
+ else
11
+ error(message)
12
+ redirect_back(fallback_location: '/')
13
+ end
14
+ false
15
+ end
16
+ end
@@ -7,11 +7,13 @@ module ForemanBootdisk
7
7
  module V2
8
8
  class DisksController < ::Api::V2::BaseController
9
9
  include ::Api::Version2
10
+ include AllowedActions
10
11
 
11
12
  resource_description do
12
13
  api_base_url '/bootdisk/api'
13
14
  end
14
15
 
16
+ before_action :bootdisk_type_allowed?, only: :generic
15
17
  before_action :find_resource, only: :host
16
18
  skip_after_action :log_response_body
17
19
 
@@ -34,10 +36,17 @@ module ForemanBootdisk
34
36
  def host
35
37
  host = @disk
36
38
  if params[:full]
37
- ForemanBootdisk::ISOGenerator.generate_full_host(host) do |iso|
38
- send_file(iso, filename: "#{host.name}#{ForemanBootdisk::ISOGenerator.token_expiry(host)}.iso")
39
+ return unless bootdisk_type_allowed?('full_host')
40
+ begin
41
+ ForemanBootdisk::ISOGenerator.generate_full_host(host) do |iso|
42
+ send_file(iso, filename: "#{host.name}#{ForemanBootdisk::ISOGenerator.token_expiry(host)}.iso")
43
+ end
44
+ rescue ::Foreman::Exception => e
45
+ raise e unless e.code == 'ERF42-2893'
46
+ render_error json: { error: _('Host is not in build mode')}, status: :method_not_allowed
39
47
  end
40
48
  else
49
+ return unless bootdisk_type_allowed?
41
50
  # EFI not supported for iPXE host bootdisk
42
51
  tmpl = host.bootdisk_template_render
43
52
  ForemanBootdisk::ISOGenerator.generate(ipxe: tmpl) do |iso|
@@ -7,11 +7,14 @@ module ForemanBootdisk
7
7
  module V2
8
8
  class SubnetDisksController < ::Api::V2::BaseController
9
9
  include ::Api::Version2
10
+ include AllowedActions
10
11
 
11
12
  resource_description do
12
13
  api_base_url '/bootdisk/api'
13
14
  end
14
15
 
16
+ rescue_from ActiveRecord::RecordNotFound, :with => :subnet_not_found
17
+ before_action :bootdisk_type_allowed?, only: :subnet
15
18
  before_action :find_resource, only: :subnet
16
19
 
17
20
  skip_after_action :log_response_body
@@ -42,6 +45,10 @@ module ForemanBootdisk
42
45
  def resource_scope
43
46
  Subnet.authorized('view_subnets')
44
47
  end
48
+
49
+ def subnet_not_found
50
+ not_found ("Subnet not found by id '%s'") % params[:id]
51
+ end
45
52
  end
46
53
  end
47
54
  end
@@ -4,7 +4,14 @@ require 'uri'
4
4
 
5
5
  module ForemanBootdisk
6
6
  class DisksController < ::ApplicationController
7
- before_action :find_resource, only: %w[host full_host subnet]
7
+ include AllowedActions
8
+ include PrettyError
9
+
10
+ helper DiskHelper
11
+
12
+ before_action :bootdisk_type_allowed?, except: %i[help bootdisk_options]
13
+
14
+ before_action :find_resource, only: %w[host full_host bootdisk_options]
8
15
 
9
16
  # as this engine is isolated, we need to include url helpers from core explicitly
10
17
  # to render help page layout
@@ -36,6 +43,8 @@ module ForemanBootdisk
36
43
  return
37
44
  end
38
45
 
46
+ prolong_token(host)
47
+
39
48
  ForemanBootdisk::ISOGenerator.generate(ipxe: tmpl) do |iso|
40
49
  send_file(iso, filename: "#{host.name}.iso")
41
50
  end
@@ -43,33 +52,39 @@ module ForemanBootdisk
43
52
 
44
53
  def full_host
45
54
  host = @disk
46
- ForemanBootdisk::ISOGenerator.generate_full_host(host) do |iso|
47
- send_file(iso, filename: "#{host.name}#{ForemanBootdisk::ISOGenerator.token_expiry(host)}.iso")
55
+
56
+ prolong_token(host)
57
+ begin
58
+ ForemanBootdisk::ISOGenerator.generate_full_host(host) do |iso|
59
+ send_file(iso, filename: "#{host.name}#{ForemanBootdisk::ISOGenerator.token_expiry(host)}.iso")
60
+ end
61
+ rescue ::Foreman::Exception => e
62
+ raise e unless e.code == 'ERF42-2893'
63
+ error _('Host is not in build mode.')
64
+ redirect_back(fallback_location: '/')
48
65
  end
49
66
  end
50
67
 
51
- def subnet
68
+ def help; end
69
+
70
+ def bootdisk_options
52
71
  host = @disk
53
- begin
54
- subnet = host.try(:subnet) || raise(::Foreman::Exception.new(N_('Subnet is not assigned to the host %s'), host.name))
55
- subnet.tftp || raise(::Foreman::Exception.new(N_('TFTP feature not enabled for subnet %s'), subnet.name))
56
- subnet.httpboot || ForemanBootdisk.logger.warn('HTTPBOOT feature is not enabled for subnet %s, UEFI may not be available for bootdisk' % subnet.name)
57
72
 
58
- tmpl_bios = ForemanBootdisk::Renderer.new.generic_template_render(subnet)
59
- tmpl_efi = ForemanBootdisk::Renderer.new.generic_efi_template_render(subnet)
60
- rescue StandardError => e
61
- error_rendering(e)
62
- redirect_back(fallback_location: '/')
63
- return
64
- end
73
+ return not_found unless host
65
74
 
66
- ForemanBootdisk::ISOGenerator.generate(ipxe: tmpl_bios, grub: tmpl_efi) do |iso|
67
- send_file(iso, filename: "bootdisk_subnet_#{subnet.name}.iso")
75
+ respond_to do |format|
76
+ format.json do
77
+ render json: {
78
+ bootdiskOptions: {
79
+ bootdiskDownloadable: !!host.bootdisk_downloadable?,
80
+ architectureName: host.architecture.name,
81
+ actions: bootdisk_allowed_actions(host),
82
+ },
83
+ }, status: :ok
84
+ end
68
85
  end
69
86
  end
70
87
 
71
- def help; end
72
-
73
88
  private
74
89
 
75
90
  def resource_scope(_controller = controller_name)
@@ -81,5 +96,42 @@ module ForemanBootdisk
81
96
  error("#{msg}: #{exception.message}")
82
97
  ::Foreman::Logging.exception(msg, exception)
83
98
  end
99
+
100
+ def prolong_token(host)
101
+ return if Setting[:token_duration] == 0 || host.token.nil?
102
+
103
+ # update build token
104
+ token = host.token
105
+ token.update(expires: Time.zone.now + Setting[:token_duration].minutes)
106
+ end
107
+
108
+ def bootdisk_allowed_actions(host)
109
+ return [] unless host.bootdisk_downloadable?
110
+
111
+ allowed = %w[host full_host].each_with_object([]) do |action, actions|
112
+ opts = {
113
+ controller: 'foreman_bootdisk/disks',
114
+ action: action,
115
+ id: host
116
+ }
117
+ next unless User.current.allowed_to?(opts) && Setting::Bootdisk.allowed_types.include?(action)
118
+
119
+ hostname = host.name.split('.')[0]
120
+ title = action == 'host' ? _("Host '%s' image") % hostname : _("Full host '%s' image") % hostname
121
+ disable_full_host = action == 'full_host' && !host.build?
122
+ actions << {
123
+ title: title,
124
+ link: "/bootdisk/disks/#{action}s/#{host.id}",
125
+ disabled: disable_full_host ? true : false,
126
+ description: disable_full_host ? _('Host is not in build mode') : nil
127
+ }
128
+ end
129
+ return allowed unless User.current.allowed_to?({controller: 'foreman_bootdisk/disks', action: 'help'})
130
+
131
+ allowed.push({
132
+ title: _('Boot disk help'),
133
+ link: '/bootdisk/disks/help'
134
+ })
135
+ end
84
136
  end
85
137
  end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ForemanBootdisk
4
+ class SubnetDisksController < ::ApplicationController
5
+ include PrettyError
6
+
7
+ before_action :find_resource, only: :subnet
8
+
9
+ # as this engine is isolated, we need to include url helpers from core explicitly
10
+ # to render help page layout
11
+ include Rails.application.routes.url_helpers
12
+
13
+ def subnet
14
+ begin
15
+ @subnet.tftp || raise(::Foreman::Exception.new(N_('TFTP feature not enabled for subnet %s'), @subnet.name))
16
+ @subnet.httpboot || ForemanBootdisk.logger.warn('HTTPBOOT feature is not enabled for subnet %s, UEFI may not be available for bootdisk' % @subnet.name)
17
+
18
+ tmpl_bios = ForemanBootdisk::Renderer.new.generic_template_render(@subnet)
19
+ tmpl_efi = ForemanBootdisk::Renderer.new.generic_efi_template_render(@subnet)
20
+ rescue StandardError => e
21
+ error_rendering(e)
22
+ redirect_back(fallback_location: '/')
23
+ return
24
+ end
25
+
26
+ ForemanBootdisk::ISOGenerator.generate(ipxe: tmpl_bios, grub: tmpl_efi) do |iso|
27
+ send_file(iso, filename: "bootdisk_subnet_#{@subnet.name}.iso")
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def resource_scope(_controller = controller_name)
34
+ Subnet.authorized(:view_subnets)
35
+ end
36
+
37
+ def find_resource
38
+ @subnet = Subnet.find(params[:id])
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BootdiskLinksHelper
4
+ # Core Foreman helpers can't look up a URL against a mounted engine
5
+ def display_bootdisk_link_if_authorized(name, options = {}, html_options = {})
6
+ if bootdisk_authorized_for(options)
7
+ link_to(name, bootdisk_url(options), html_options)
8
+ else
9
+ ''
10
+ end
11
+ end
12
+
13
+ def bootdisk_url(options)
14
+ ForemanBootdisk::Engine.routes.url_for(options.merge(only_path: true, script_name: foreman_bootdisk_path))
15
+ end
16
+
17
+ def bootdisk_authorized_for(options)
18
+ User.current.allowed_to?(options)
19
+ end
20
+
21
+ def divider
22
+ tag(:li, class: 'divider')
23
+ end
24
+
25
+ def bootdisk_help_link
26
+ display_bootdisk_link_if_authorized(
27
+ _('Boot disk Help'),
28
+ {
29
+ controller: 'foreman_bootdisk/disks',
30
+ action: 'help'
31
+ },
32
+ class: 'la'
33
+ )
34
+ end
35
+
36
+ def bootdisk_title_action_buttons(actions)
37
+ title_actions(
38
+ button_group(
39
+ select_action_button(
40
+ _('Boot disk'), { class: 'btn btn-group' },
41
+ actions
42
+ )
43
+ )
44
+ )
45
+ end
46
+ end
@@ -2,51 +2,11 @@
2
2
 
3
3
  module ForemanBootdisk
4
4
  module HostsHelperExt
5
+ include BootdiskLinksHelper
6
+
5
7
  def host_title_actions(host)
6
8
  if host.bootdisk_downloadable?
7
- title_actions(
8
- button_group(
9
- select_action_button(
10
- _('Boot disk'), { class: 'btn btn-group' },
11
- display_bootdisk_link_if_authorized(
12
- _("Host '%s' image") % host.name.split('.')[0],
13
- {
14
- controller: 'foreman_bootdisk/disks',
15
- action: 'host',
16
- id: host
17
- },
18
- class: 'la'
19
- ),
20
- display_bootdisk_link_if_authorized(
21
- _("Full host '%s' image") % host.name.split('.')[0],
22
- {
23
- controller: 'foreman_bootdisk/disks',
24
- action: 'full_host',
25
- id: host
26
- },
27
- class: 'la'
28
- ),
29
- content_tag(:li, '', class: 'divider'),
30
- display_bootdisk_link_if_authorized(
31
- _('Generic image'),
32
- {
33
- controller: 'foreman_bootdisk/disks',
34
- action: 'generic'
35
- },
36
- class: 'la'
37
- ),
38
- display_bootdisk_for_subnet(host),
39
- content_tag(:li, '', class: 'divider'),
40
- display_bootdisk_link_if_authorized(
41
- _('Help'), {
42
- controller: 'foreman_bootdisk/disks',
43
- action: 'help'
44
- },
45
- class: 'la'
46
- )
47
- )
48
- )
49
- )
9
+ bootdisk_title_action_buttons(host_action_buttons(host))
50
10
  else
51
11
  bootdisk_button_disabled(host)
52
12
  end
@@ -95,5 +55,59 @@ module ForemanBootdisk
95
55
  def bootdisk_authorized_for(options)
96
56
  User.current.allowed_to?(options)
97
57
  end
58
+
59
+ def host_action_buttons(host)
60
+ actions = []
61
+
62
+ allowed_actions = Setting::Bootdisk.allowed_types
63
+ return '' unless allowed_actions
64
+
65
+ host_image_link = display_bootdisk_link_if_authorized(
66
+ _("Host '%s' image") % host.name.split('.')[0],
67
+ {
68
+ controller: 'foreman_bootdisk/disks',
69
+ action: 'host',
70
+ id: host
71
+ },
72
+ class: 'la'
73
+ )
74
+
75
+ full_host_image_link = display_bootdisk_link_if_authorized(
76
+ _("Full host '%s' image") % host.name.split('.')[0],
77
+ {
78
+ controller: 'foreman_bootdisk/disks',
79
+ action: 'full_host',
80
+ id: host
81
+ },
82
+ class: 'la'
83
+ )
84
+
85
+ full_host_blind_link = if bootdisk_authorized_for({controller: 'foreman_bootdisk/disks', action: 'full_host', id: host})
86
+ link_to(_("Full host '%s' image") % host.name.split('.')[0],
87
+ '#',
88
+ class: 'la btn btn-info',
89
+ disabled: true,
90
+ title: _('Host is not in build mode')
91
+ )
92
+ else
93
+ ''
94
+ end
95
+
96
+ actions << host_image_link if allowed_actions.include?('host')
97
+ if allowed_actions.include?('full_host')
98
+ if host.build?
99
+ actions << full_host_image_link
100
+ else
101
+ actions << full_host_blind_link
102
+ end
103
+ end
104
+
105
+
106
+ actions << divider if (host_image_link.present? && allowed_actions.include?('host')) || (full_host_image_link.present? && allowed_actions.include?('full_host'))
107
+
108
+ actions << bootdisk_help_link
109
+
110
+ actions
111
+ end
98
112
  end
99
113
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ForemanBootdisk
4
+ module PrettyError
5
+ extend ActiveSupport::Concern
6
+
7
+ def error_rendering(exception)
8
+ msg = _('Failed to render boot disk template')
9
+ error("#{msg}: #{exception.message}")
10
+ ::Foreman::Logging.exception(msg, exception)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ForemanBootdisk
4
+ module SubnetsHelperExt
5
+ include BootdiskLinksHelper
6
+
7
+ def display_bootdisk_for_subnet(subnet)
8
+ if (proxy = subnet.tftp || subnet.httpboot) && proxy.has_feature?('Templates') && Setting::Bootdisk.allowed_types.include?('subnet')
9
+ display_bootdisk_link_if_authorized(
10
+ _("Subnet generic image"), {
11
+ controller: 'foreman_bootdisk/subnet_disks',
12
+ action: 'subnet',
13
+ id: subnet.id
14
+ },
15
+ class: 'la'
16
+ )
17
+ else
18
+ ''
19
+ end
20
+ end
21
+
22
+ def display_bootdisk_title_buttons
23
+
24
+ actions = []
25
+
26
+ generic_image_link = display_bootdisk_link_if_authorized(
27
+ _('Generic image'),
28
+ {
29
+ controller: 'foreman_bootdisk/disks',
30
+ action: 'generic'
31
+ },
32
+ class: 'la'
33
+ )
34
+
35
+ if Setting::Bootdisk.allowed_types&.include?('generic')
36
+ actions << generic_image_link
37
+ actions << divider
38
+ end
39
+
40
+ actions << bootdisk_help_link
41
+
42
+ bootdisk_title_action_buttons(actions)
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DiskHelper
4
+ def mark_disabled_bootdisk_type(type)
5
+ return '' if Setting::Bootdisk.allowed_types&.include?(type)
6
+ '*'
7
+ end
8
+ end
@@ -3,6 +3,20 @@
3
3
  module ForemanBootdisk
4
4
  module Scope
5
5
  class Bootdisk < ::Foreman::Renderer::Scope::Provisioning
6
+ extend ApipieDSL::Class
7
+
8
+ apipie :class, 'Macros related to provisioning via boot disk' do
9
+ name 'Bootdisk'
10
+ sections only: %w[all provisioning]
11
+ end
12
+
13
+ apipie :method, 'Generates URL for boot chain' do
14
+ optional :mac, String, 'MAC address of the host', default: 'MAC address of the current host'
15
+ optional :action, String, 'Bootloader to use', default: 'iPXE'
16
+ returns String, desc: 'URL for boot chain'
17
+ example 'bootdisk_chain_url #=> "http://foreman.some.host.fqdn/unattended/iPXE?mac=00%3A11%3A22%3A33%3A44%3A55"'
18
+ example 'bootdisk_chain_url("00:11:22:33:44:55") #=> "http://foreman.some.host.fqdn/unattended/iPXE?mac=00%3A11%3A22%3A33%3A44%3A55"'
19
+ end
6
20
  def bootdisk_chain_url(mac = host.try(:mac), action = 'iPXE')
7
21
  url = foreman_url(action)
8
22
  u = URI.parse(url)
@@ -14,6 +28,16 @@ module ForemanBootdisk
14
28
  u.to_s
15
29
  end
16
30
 
31
+ apipie :method, 'Always raises an error with a description provided as an argument' do
32
+ desc 'This method is useful for aborting script execution if some of the conditions are not met'
33
+ list :args, desc: 'Description for the error'
34
+ raises error: ::Foreman::Exception, desc: 'The error is always being raised'
35
+ returns nil, desc: "Doesn't return anything"
36
+ example "<%
37
+ interface = @host.provision_interface #=> interface = nil
38
+ bootdisk_raise(N_('Host has no provisioning interface defined')) unless interface #=> Foreman::Exception is raised and the execution of the script is aborted
39
+ %>"
40
+ end
17
41
  def bootdisk_raise(*args)
18
42
  raise ::Foreman::Exception.new(*args)
19
43
  end
@@ -4,6 +4,8 @@ require 'uri'
4
4
 
5
5
  module ForemanBootdisk
6
6
  module HostExt
7
+ extend ApipieDSL::Extension
8
+
7
9
  def bootdisk_template
8
10
  template = ProvisioningTemplate.unscoped.find_by(name: Setting[:bootdisk_host_template])
9
11
  unless template
@@ -36,6 +38,10 @@ module ForemanBootdisk
36
38
  def can_be_built?
37
39
  super || (managed? && SETTINGS[:unattended] && bootdisk_build? && !build?)
38
40
  end
41
+
42
+ apipie_update :class do
43
+ property :bootdisk_build?, one_of: [true, false], desc: 'Returns true if provision method for this host is bootdisk, false otherwise'
44
+ end
39
45
  end
40
46
  end
41
47
 
@@ -42,8 +42,16 @@ module ForemanBootdisk
42
42
  end
43
43
 
44
44
  def bootdisk_generate_iso_image
45
- ForemanBootdisk::ISOGenerator.generate(ipxe: bootdisk_template_render, dir: Dir.tmpdir) do |image|
46
- FileUtils.mv image, bootdisk_isofile
45
+ if self.build? && self.provisioning_template(kind: :PXELinux) && self.provisioning_template(kind: :PXEGrub2)
46
+ logger.info format('Generating FULL HOST ISO image for %s', name)
47
+ ForemanBootdisk::ISOGenerator.generate_full_host(self, dir: Dir.tmpdir) do |image|
48
+ FileUtils.mv image, bootdisk_isofile
49
+ end
50
+ else
51
+ logger.info format('Generating HOST ISO image for %s', name)
52
+ ForemanBootdisk::ISOGenerator.generate(ipxe: bootdisk_template_render, dir: Dir.tmpdir) do |image|
53
+ FileUtils.mv image, bootdisk_isofile
54
+ end
47
55
  end
48
56
  end
49
57
 
@@ -60,7 +68,6 @@ module ForemanBootdisk
60
68
  end
61
69
 
62
70
  def setGenerateIsoImage
63
- logger.info format('Generating ISO image for %s', name)
64
71
  bootdisk_generate_iso_image
65
72
  rescue StandardError => e
66
73
  failure format(_('Failed to generate ISO image for instance %{name}: %{message}'), name: name, message: e.message), e
@@ -21,12 +21,21 @@ class Setting
21
21
  set('bootdisk_generic_efi_host_template', N_('Grub2 template to use for generic EFI host boot disks'),
22
22
  'Boot disk Grub2 EFI - generic host', N_('Generic Grub2 EFI image template'), nil, collection: templates),
23
23
  set('bootdisk_mkiso_command', N_('Command to generate ISO image, use genisoimage or mkisofs'), 'genisoimage', N_('ISO generation command')),
24
- set('bootdisk_cache_media', N_('Installation media files will be cached for full host images'), true, N_('Installation media caching'))
24
+ set('bootdisk_cache_media', N_('Installation media files will be cached for full host images'), true, N_('Installation media caching')),
25
+ set('bootdisk_allowed_types', N_('List of allowed bootdisk types, remove type to disable it'), Setting::Bootdisk.bootdisk_types, N_('Allowed bootdisk types'))
25
26
  ]
26
27
  end
27
28
 
28
29
  def self.humanized_category
29
30
  N_('Boot disk')
30
31
  end
32
+
33
+ def self.bootdisk_types
34
+ %w(generic host full_host subnet)
35
+ end
36
+
37
+ def self.allowed_types
38
+ Setting['bootdisk_allowed_types']
39
+ end
31
40
  end
32
41
  end