Revision 7f25f394
Added by Leos Stejskal about 3 years ago
app/controllers/api/v2/registration_controller.rb | ||
---|---|---|
prepare_host
|
||
host_setup_insights
|
||
host_setup_remote_execution
|
||
host_setup_packages
|
||
host_setup_extension
|
||
@template = @host.initial_configuration_template
|
||
raise ActiveRecord::Rollback if @template.nil?
|
app/controllers/concerns/foreman/controller/registration.rb | ||
---|---|---|
registration_url: registration_url,
|
||
setup_insights: ActiveRecord::Type::Boolean.new.deserialize(params['setup_insights']),
|
||
setup_remote_execution: ActiveRecord::Type::Boolean.new.deserialize(params['setup_remote_execution']),
|
||
packages: params['packages'],
|
||
repo: params['repo'],
|
||
repo_gpg_key_url: params['repo_gpg_key_url'],
|
||
}
|
||
... | ... | |
rex_param.save!
|
||
end
|
||
|
||
def host_setup_packages
|
||
return if params['packages'].to_s.blank?
|
||
|
||
insights_param = HostParameter.find_or_initialize_by(host: @host, name: 'host_packages', key_type: 'string')
|
||
insights_param.value = params['packages']
|
||
insights_param.save!
|
||
end
|
||
|
||
def api_authorization_token
|
||
scope = [{
|
||
controller: :registration,
|
app/controllers/concerns/foreman/controller/registration_commands.rb | ||
---|---|---|
|
||
def command
|
||
args_query = "?#{registration_args.to_query}"
|
||
"curl #{insecure} -s '#{endpoint}#{args_query if args_query != '?'}' #{command_headers} | bash"
|
||
"curl#{insecure} -s '#{endpoint}#{args_query if args_query != '?'}' #{command_headers} | bash"
|
||
end
|
||
|
||
def registration_args
|
||
... | ... | |
end
|
||
|
||
def insecure
|
||
registration_params['insecure'] ? '--insecure' : ''
|
||
registration_params['insecure'] ? ' --insecure' : ''
|
||
end
|
||
|
||
def endpoint
|
||
... | ... | |
end
|
||
|
||
def command_headers
|
||
hours = (registration_params['jwt_expiration'].presence || 4).to_i.hours.to_i
|
||
scope = [{ controller: :registration, actions: [:global, :host] }]
|
||
jwt = User.current.jwt_token!(expiration: hours, scope: scope)
|
||
jwt_args = {
|
||
scope: [{ controller: :registration, actions: [:global, :host] }],
|
||
}
|
||
|
||
"-H 'Authorization: Bearer #{jwt}'"
|
||
if registration_params['jwt_expiration'].present?
|
||
jwt_args[:expiration] = registration_params['jwt_expiration'].to_i.hours.to_i if registration_params['jwt_expiration'] != 'unlimited'
|
||
else
|
||
jwt_args[:expiration] = 4.hours.to_i
|
||
end
|
||
|
||
"-H 'Authorization: Bearer #{User.current.jwt_token!(**jwt_args)}'"
|
||
end
|
||
|
||
def host_config_params
|
||
organization = User.current.my_organizations.find(registration_params['organization_id']) if registration_params['organization_id'].present?
|
||
location = User.current.my_locations.find(registration_params['location_id']) if registration_params['location_id'].present?
|
||
host_group = Hostgroup.authorized(:view_hostgroups).find(registration_params['hostgroup_id']) if registration_params["hostgroup_id"].present?
|
||
operatingsystem = Operatingsystem.authorized(:view_operatingsystems).find(registration_params['operatingsystem_id']) if registration_params["operatingsystem_id"].present?
|
||
|
||
Host.new(organization: organization, location: location, hostgroup: host_group, operatingsystem: operatingsystem).params
|
||
end
|
||
end
|
app/controllers/registration_commands_controller.rb | ||
---|---|---|
class RegistrationCommandsController < ApplicationController
|
||
include Foreman::Controller::RegistrationCommands
|
||
|
||
def new
|
||
form_options
|
||
def form_data
|
||
render json: {
|
||
organizations: User.current.my_organizations.select(:id, :name),
|
||
locations: User.current.my_locations.select(:id, :name),
|
||
hostGroups: Hostgroup.authorized(:view_hostgroups).includes([:operatingsystem]),
|
||
operatingSystems: Operatingsystem.authorized(:view_operatingsystems),
|
||
smartProxies: Feature.find_by(name: 'Registration')&.smart_proxies,
|
||
configParams: host_config_params,
|
||
pluginData: plugin_data,
|
||
}
|
||
end
|
||
|
||
def operatingsystem_template
|
||
os = Operatingsystem.authorized(:view_operatingsystems).find(params[:id])
|
||
template_kind = TemplateKind.find_by(name: 'host_init_config')
|
||
template = os.os_default_templates
|
||
.find_by(template_kind: template_kind)&.provisioning_template
|
||
|
||
if template
|
||
render json: { template: { name: template.name, path: edit_provisioning_template_path(template) } }
|
||
else
|
||
render json: { template: { name: nil, os_path: edit_operatingsystem_path(os)} }
|
||
end
|
||
end
|
||
|
||
def create
|
||
form_options
|
||
@command = command
|
||
render json: { command: command }
|
||
end
|
||
|
||
private
|
||
|
||
def form_options
|
||
@host_groups = Hostgroup.authorized(:view_hostgroups).select(:id, :name)
|
||
@operating_systems = Operatingsystem.authorized(:view_operatingsystems).select(:id, :title)
|
||
@smart_proxies = Feature.find_by(name: 'Registration')&.smart_proxies || []
|
||
end
|
||
|
||
def ignored_query_args
|
||
['utf8', 'authenticity_token', 'commit', 'action', 'locale', 'controller', 'jwt_expiration', 'smart_proxy_id', 'insecure']
|
||
end
|
||
|
||
def registration_params
|
||
params
|
||
if params['registration_command']
|
||
params['registration_command'].transform_keys(&:underscore)
|
||
else
|
||
params
|
||
end
|
||
end
|
||
|
||
# Extension point for plugins
|
||
def plugin_data
|
||
{}
|
||
end
|
||
end
|
app/registries/foreman/access_permissions.rb | ||
---|---|---|
:puppetclasses => pc_ajax_actions,
|
||
:subnets => subnets_ajax_actions,
|
||
:interfaces => [:new, :random_name],
|
||
:registration_commands => [:new, :create],
|
||
:registration_commands => [:form_data, :operatingsystem_template, :create],
|
||
:"api/v2/hosts" => [:create],
|
||
:"api/v2/interfaces" => [:create],
|
||
:"api/v2/tasks" => [:index],
|
app/registries/menu/loader.rb | ||
---|---|---|
menu.item :hosts, :caption => N_('All Hosts')
|
||
menu.item :newhost, :caption => N_('Create Host'),
|
||
:url_hash => {:controller => '/hosts', :action => 'new'}
|
||
menu.item :register_hosts, :caption => N_('Register Host')
|
||
menu.item :register_hosts, :caption => N_('Register Host'),
|
||
:url => '/hosts/register',
|
||
:url_hash => { :controller => 'hosts', :action => 'create' }
|
||
if SETTINGS[:unattended]
|
||
menu.divider :caption => N_('Provisioning Setup')
|
||
menu.item :architectures, :caption => N_('Architectures')
|
app/views/hosts/index.html.erb | ||
---|---|---|
<%
|
||
register_btn = display_link_if_authorized(_("Register Host"), hash_for_register_hosts_path, :class => "btn btn-default")
|
||
register_btn = link_to(_("Register Host"), hash_for_register_hosts_path, :class => "btn btn-default") if authorized_for({contoller: 'hosts', action: 'create'})
|
||
%>
|
||
|
||
<% title_actions multiple_actions_select, csv_link, register_btn, button_group(new_link(_("Create Host"))) %>
|
app/views/registration_commands/_form.erb | ||
---|---|---|
<% title _('Register Host') %>
|
||
<%
|
||
options = [[_("Inherit from parameter"), ""], [_('Yes (enforce)'), 'true'], [_('No (enforce)'), 'false']]
|
||
%>
|
||
|
||
<%= form_tag({controller: 'registration_commands', action: 'create' }, method: :post, class: 'form-horizontal well') do %>
|
||
<div class='form-group'>
|
||
<label class='col-md-2 control-label'><%= _('Organization') %></label>
|
||
<div class='col-md-4'>
|
||
<p class="form-control-static">
|
||
<%= Organization.current&.name || _('No Organization selected') %>
|
||
<%= hidden_field_tag 'organization_id', Organization.current&.id %>
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div class='form-group'>
|
||
<label class='col-md-2 control-label'><%= _('Location') %></label>
|
||
<div class='col-md-4'>
|
||
<p class="form-control-static">
|
||
<%= Location.current&.name || _('No Location selected') %>
|
||
<%= hidden_field_tag 'location_id', Location.current&.id %>
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div class='form-group'>
|
||
<label class='col-md-2 control-label' for='hostgroup_id'>
|
||
<%= _('Host Group') %>
|
||
</label>
|
||
<div class='col-md-4'>
|
||
<%= select_tag 'hostgroup_id', options_from_collection_for_select(@host_groups, :id, :name, params[:hostgroup_id]), class: 'form-control', include_blank: '' %>
|
||
</div>
|
||
</div>
|
||
<div class='form-group'>
|
||
<label class='col-md-2 control-label' for='operatingsystem_id'>
|
||
<%= _('Operating System') %>
|
||
</label>
|
||
<div class='col-md-4'>
|
||
<%= select_tag 'operatingsystem_id', options_from_collection_for_select(@operating_systems, :id, :title, params[:operatingsystem_id]), class: 'form-control', include_blank: '' %>
|
||
</div>
|
||
</div>
|
||
<div class='form-group'>
|
||
<label class='col-md-2 control-label' for='smart_proxy'>
|
||
<%= _('Proxy') %>
|
||
<% help = _('Only Smart Proxies with enabled Registration module are available') %>
|
||
<a rel="popover" data-content="<%= help %>" data-trigger="focus" data-container="body" data-html="true" tabindex="-1">
|
||
<span class="pficon pficon-info"></span>
|
||
</a>
|
||
</label>
|
||
<div class='col-md-4'>
|
||
<%= select_tag 'smart_proxy_id', options_from_collection_for_select(@smart_proxies, :id, :name, params[:smart_proxy_id]), class: 'form-control', include_blank: '' %>
|
||
</div>
|
||
</div>
|
||
<div class='form-group'>
|
||
<label class='col-md-2 control-label' for='setup_insights'>
|
||
<% help = _('If set to "Yes", Insights client will be installed and registered on Red Hat family operating systems. It has no effect on other OS families that do not support it. The inherited value is based on the `host_registration_insights` parameter. It can be inherited e.g. from host group, operating system, organization. When overidden, the selected value will be stored on host parameter level.') %>
|
||
<%= _('Setup Insights') %>
|
||
<a rel="popover" data-content="<%= help %>" data-trigger="focus" data-container="body" data-html="true" tabindex="-1">
|
||
<span class="pficon pficon-info "></span>
|
||
</a>
|
||
</label>
|
||
<div class='col-md-4'>
|
||
<%= select_tag 'setup_insights', options_for_select(options, params[:setup_insights]), class: 'form-control' %>
|
||
</div>
|
||
</div>
|
||
<div class='form-group'>
|
||
<label class='col-md-2 control-label' for='setup_remote_execution'>
|
||
<%= _('Remote Execution') %>
|
||
<% help = _('If set to "Yes", SSH keys will be installed on the registered host. The inherited value is based on the `host_registration_remote_execution` parameter. It can be inherited e.g. from host group, operating system, organization.. When overidden, the selected value will be stored on host parameter level.') %>
|
||
<a rel="popover" data-content="<%= help %>" data-trigger="focus" data-container="body" data-html="true" tabindex="-1">
|
||
<span class="pficon pficon-info "></span>
|
||
</a>
|
||
</label>
|
||
<div class='col-md-4'>
|
||
<%= select_tag 'setup_remote_execution', options_for_select(options, params[:setup_remote_execution]), class: 'form-control' %>
|
||
</div>
|
||
</div>
|
||
<div class='form-group'>
|
||
<label class='col-md-2 control-label'>
|
||
<%= _('Token lifetime (hours)') %>
|
||
<% help = _('Expiration of the authorization token.') %>
|
||
<a rel="popover" data-content="<%= help %>" data-trigger="focus" data-container="body" data-html="true" tabindex="-1">
|
||
<span class="pficon pficon-info "></span>
|
||
</a>
|
||
</label>
|
||
<div class='col-md-4'>
|
||
<%= number_field_tag 'jwt_expiration', params[:jwt_expiration] || 4, class: 'form-control', min: 1, required: true %>
|
||
</div>
|
||
</div>
|
||
<div class='form-group'>
|
||
<label class='col-md-2 control-label'>
|
||
<%= _('Insecure') %>
|
||
<% help = _('If the target machine does not trust the Foreman SSL certificate, the initial connection could be subject to Man in the middle attack. If you accept the risk and do not require the server authenticity to be verified, you can enable insecure argument for the initial curl. Note that all subsequent communication is then properly secured, because the initial request deploys the SSL certificate for the rest of the registration process.') %>
|
||
<a rel="popover" data-content="<%= help %>" data-trigger="focus" data-container="body" data-html="true" tabindex="-1">
|
||
<span class="pficon pficon-info "></span>
|
||
</a>
|
||
</label>
|
||
<div class='col-md-4'>
|
||
<%= check_box_tag 'insecure', '', params[:insecure] %>
|
||
</div>
|
||
</div>
|
||
|
||
<% pagelets_for(:global_registration).each do |pagelet| %>
|
||
<%= render_pagelet(pagelet) %>
|
||
<% end %>
|
||
|
||
<div class='form-group '>
|
||
<%= submit_tag _('Generate command'), class: 'btn btn-primary' %>
|
||
<%= link_to _('Cancel'), hosts_path, class: 'btn btn-default' %>
|
||
</div>
|
||
|
||
<% if action_name == 'create' %>
|
||
<div class='form-group '>
|
||
<label class='col-md-2 control-label'><%= _('Command') %></label>
|
||
<div class='col-md-8'>
|
||
<pre class='ellipsis white-space-normal' id='registration_command'><%= @command %></pre>
|
||
<a class='btn btn-default' onclick="tfm.hosts.copyRegistrationCommand();" ><%= _('Copy to clipboard') %></a>
|
||
</div>
|
||
</div>
|
||
<% end %>
|
||
<% end %>
|
app/views/registration_commands/create.html.erb | ||
---|---|---|
<%= render 'form' %>
|
app/views/registration_commands/new.html.erb | ||
---|---|---|
<%= render 'form' %>
|
app/views/unattended/provisioning_templates/host_init_config/host_init_config_default.erb | ||
---|---|---|
<% end -%>
|
||
curl --silent <%= '--cacert $SSL_CA_CERT' if built_https -%> -o /dev/null --noproxy \* '<%= foreman_url('built') %>'
|
||
|
||
echo "Successfully enrolled host <%= @host.name %> with Foreman."
|
||
echo "#"
|
||
echo "# Host [<%= @host.name %>] successfully enrolled."
|
||
echo "#"
|
||
|
||
exit 0
|
app/views/unattended/provisioning_templates/registration/global_registration.erb | ||
---|---|---|
#!/bin/sh
|
||
<%
|
||
headers = ["-H 'Authorization: Bearer #{@auth_token}'"]
|
||
activation_keys = [(@hostgroup.params['kt_activation_keys'] if @hostgroup), @activation_keys].compact.join(',')
|
||
-%>
|
||
|
||
# Rendered with following template parameters:
|
||
... | ... | |
<%= "\n# Setup Insights: [#{@setup_insights}]" unless @setup_insights.nil? -%>
|
||
<%= "\n# Setup Remote Execution: [#{@setup_remote_execution}]" unless @setup_remote_execution.nil? -%>
|
||
<%= "\n# Remote execution interface: [#{@remote_execution_interface}]" if @remote_execution_interface.present? -%>
|
||
<%= "\n# Packages: [#{@packages}]" if @packages.present? -%>
|
||
<%= "\n# Activation keys: [#{activation_keys}]" if activation_keys.present? -%>
|
||
|
||
|
||
if ! [ $(id -u) = 0 ]; then
|
||
... | ... | |
<%= " --data 'setup_insights=#{@setup_insights}' \\\n" unless @setup_insights.nil? -%>
|
||
<%= " --data 'setup_remote_execution=#{@setup_remote_execution}' \\\n" unless @setup_remote_execution.nil? -%>
|
||
<%= " --data 'remote_execution_interface=#{@remote_execution_interface}' \\\n" if @remote_execution_interface.present? -%>
|
||
<%= " --data 'packages=#{@packages}' \\\n" if @packages.present? -%>
|
||
|
||
}
|
||
|
||
... | ... | |
<%= " --data 'host[organization_id]=#{@organization.id}' \\\n" if @organization -%>
|
||
<%= " --data 'host[location_id]=#{@location.id}' \\\n" if @location -%>
|
||
<%= " --data 'host[hostgroup_id]=#{@hostgroup.id}' \\\n" if @hostgroup -%>
|
||
<%= " --data 'host[lifecycle_environment_id]=#{@lifecycle_environment_id}' \\\n" if @lifecycle_environment_id.present? -%>
|
||
<%= " --data 'setup_insights=#{@setup_insights}' \\\n" unless @setup_insights.nil? -%>
|
||
<%= " --data 'setup_remote_execution=#{@setup_remote_execution}' \\\n" unless @setup_remote_execution.nil? -%>
|
||
<%= " --data 'remote_execution_interface=#{@remote_execution_interface}' \\\n" if @remote_execution_interface.present? -%>
|
||
<%= " --data 'packages=#{@packages}' \\\n" if @packages.present? -%>
|
||
|
||
}
|
||
|
||
<% if @force -%>
|
||
yum remove -y katello-ca-consumer*
|
||
<% end -%>
|
||
|
||
CONSUMER_RPM=$(mktemp --suffix .rpm)
|
||
curl --silent --output $CONSUMER_RPM <%= subscription_manager_configuration_url(hostname: @url_host) %>
|
||
|
||
... | ... | |
|
||
rm -f $CONSUMER_RPM
|
||
|
||
subscription-manager register --org='<%= @organization.label %>' --activationkey='<%= @activation_key %>' || exit 1
|
||
subscription-manager register <%= '--force' if @force %> --org='<%= @organization.label %>' --activationkey='<%= activation_keys %>' || <%= @ignore_subman_errors ? 'true' : 'exit 1' %>
|
||
register_katello_host | bash
|
||
else
|
||
register_host | bash
|
config/routes.rb | ||
---|---|---|
get 'random_name', only: :new
|
||
get 'preview_host_collection'
|
||
|
||
get 'register', to: 'registration_commands#new'
|
||
get 'register' => 'react#index'
|
||
post 'register', to: 'registration_commands#create'
|
||
get 'register/data', to: 'registration_commands#form_data'
|
||
get 'register/os/:id', to: 'registration_commands#operatingsystem_template'
|
||
end
|
||
|
||
constraints(host_id: /[^\/]+/) do
|
test/controllers/api/v2/registration_commands_controller_test.rb | ||
---|---|---|
assert_response :success
|
||
response = ActiveSupport::JSON.decode(@response.body)['registration_command']
|
||
|
||
assert_includes response, "curl -s 'http://test.host/register'"
|
||
assert_includes response, "curl -s 'http://test.host/register'"
|
||
assert_includes response, "-H 'Authorization: Bearer"
|
||
end
|
||
|
||
... | ... | |
operatingsystem_id: operatingsystems(:redhat).id,
|
||
setup_insights: 'false',
|
||
setup_remote_execution: 'false',
|
||
packages: 'pkg1',
|
||
}
|
||
|
||
post :create, params: params
|
||
... | ... | |
assert_includes response, "operatingsystem_id=#{operatingsystems(:redhat).id}"
|
||
assert_includes response, 'setup_insights=false'
|
||
assert_includes response, 'setup_remote_execution=false'
|
||
assert_includes response, 'packages=pkg1'
|
||
end
|
||
|
||
test 'with params ignored in url' do
|
||
test 'with params ignored in URL' do
|
||
params = {
|
||
insecure: true,
|
||
jwt_expiration: 23,
|
test/controllers/api/v2/registration_controller_test.rb | ||
---|---|---|
refute HostParameter.find_by(host: host, name: 'host_registration_remote_execution').value
|
||
end
|
||
end
|
||
|
||
context 'packages' do
|
||
test 'without param' do
|
||
params = { packages: '' }.merge(host_params)
|
||
post :host, params: params, session: set_session_user
|
||
assert_response :success
|
||
|
||
host = Host.find_by(name: params[:host][:name]).reload
|
||
assert_nil HostParameter.find_by(host: host, name: 'host_packages')
|
||
end
|
||
|
||
test 'with param' do
|
||
params = { packages: 'pkg1 pkg2' }.merge(host_params)
|
||
post :host, params: params, session: set_session_user
|
||
assert_response :success
|
||
|
||
host = Host.find_by(name: params[:host][:name]).reload
|
||
assert HostParameter.find_by(host: host, name: 'host_packages').value
|
||
end
|
||
end
|
||
end
|
||
end
|
test/controllers/registration_commands_controller_test.rb | ||
---|---|---|
require 'test_helper'
|
||
|
||
class RegistrationCommandsControllerTest < ActionController::TestCase
|
||
test 'new' do
|
||
get :new, session: set_session_user
|
||
assert_response :success
|
||
assert_template :new
|
||
end
|
||
|
||
describe 'create' do
|
||
test 'create' do
|
||
params = { organization: taxonomies(:organization1).id, location: taxonomies(:location1).id }
|
||
test 'with params' do
|
||
params = {
|
||
organizationId: taxonomies(:organization1).id,
|
||
locationId: taxonomies(:location1).id,
|
||
hostgroupId: hostgroups(:common).id,
|
||
operatingsystemId: operatingsystems(:redhat).id,
|
||
}
|
||
post :create, params: params, session: set_session_user
|
||
command = JSON.parse(@response.body)['command']
|
||
|
||
assert_includes command, 'organizationId='
|
||
assert_includes command, 'locationId='
|
||
assert_includes command, 'hostgroupId='
|
||
assert_includes command, 'operatingsystemId='
|
||
end
|
||
|
||
test 'with params ignored in URL' do
|
||
params = {
|
||
smart_proxy_id: smart_proxies(:one).id,
|
||
insecure: true,
|
||
jwt_expiration: 23,
|
||
}
|
||
|
||
post :create, params: params, session: set_session_user
|
||
command = JSON.parse(@response.body)['command']
|
||
|
||
assert_includes command, "curl --insecure -s '#{smart_proxies(:one).url}/register"
|
||
refute command.include?('smart_proxy_id')
|
||
refute command.include?('insecure=true')
|
||
refute command.include?('jwt_expiration')
|
||
end
|
||
|
||
context 'host_params' do
|
||
let(:params) { { organization: taxonomies(:organization1).id, location: taxonomies(:location1).id } }
|
||
|
||
before do
|
||
CommonParameter.where(name: 'host_registration_insights').destroy_all
|
||
CommonParameter.where(name: 'setup_remote_execution').destroy_all
|
||
end
|
||
|
||
test 'inherit value' do
|
||
post :create, params: params, session: set_session_user
|
||
|
||
refute JSON.parse(@response.body)['command'].include?('setup_insights')
|
||
refute JSON.parse(@response.body)['command'].include?('setup_remote_execution')
|
||
end
|
||
|
||
test 'yes (override)' do
|
||
post :create, params: params.merge(setup_insights: true, setup_remote_execution: true), session: set_session_user
|
||
|
||
assert JSON.parse(@response.body)['command'].include?('setup_insights=true')
|
||
assert JSON.parse(@response.body)['command'].include?('setup_remote_execution=true')
|
||
end
|
||
|
||
test 'no (override)' do
|
||
post :create, params: params.merge(setup_insights: false, setup_remote_execution: false), session: set_session_user
|
||
|
||
assert JSON.parse(@response.body)['command'].include?('setup_insights=false')
|
||
assert JSON.parse(@response.body)['command'].include?('setup_remote_execution=false')
|
||
end
|
||
end
|
||
|
||
context 'jwt' do
|
||
test 'with default expiration' do
|
||
post :create, session: set_session_user
|
||
command = JSON.parse(@response.body)['command']
|
||
parsed_token = command.scan(/(?<=Bearer )(.*)(?=.*)(?=\')/).flatten[0]
|
||
assert JwtToken.new(parsed_token).decode['exp']
|
||
end
|
||
|
||
test 'with expiration' do
|
||
post :create, params: { jwt_expiration: 23 }, session: set_session_user
|
||
command = JSON.parse(@response.body)['command']
|
||
parsed_token = command.scan(/(?<=Bearer )(.*)(?=.*)(?=\')/).flatten[0]
|
||
assert JwtToken.new(parsed_token).decode['exp']
|
||
end
|
||
|
||
test 'unlimited' do
|
||
post :create, params: { jwt_expiration: 'unlimited' }, session: set_session_user
|
||
command = JSON.parse(@response.body)['command']
|
||
parsed_token = command.scan(/(?<=Bearer )(.*)(?=.*)(?=\')/).flatten[0]
|
||
|
||
assert_response :success
|
||
assert_template :create
|
||
refute JwtToken.new(parsed_token).decode['exp']
|
||
end
|
||
end
|
||
end
|
||
end
|
webpack/assets/javascripts/react_app/components/common/LabelIcon/LabelIcon.test.js | ||
---|---|---|
import { testComponentSnapshotsWithFixtures } from '../../../common/testHelpers';
|
||
|
||
import LabelIcon from './index';
|
||
|
||
describe('LabelIcon', () => {
|
||
testComponentSnapshotsWithFixtures(LabelIcon, { 'renders': {text: 'Yay, label help!'} });
|
||
})
|
webpack/assets/javascripts/react_app/components/common/LabelIcon/__snapshots__/LabelIcon.test.js.snap | ||
---|---|---|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||
|
||
exports[`LabelIcon renders 1`] = `
|
||
<Popover
|
||
bodyContent="Yay, label help!"
|
||
>
|
||
<button
|
||
className="pf-c-form__group-label-help"
|
||
onClick={[Function]}
|
||
>
|
||
<HelpIcon
|
||
color="currentColor"
|
||
noVerticalAlign={true}
|
||
size="sm"
|
||
/>
|
||
</button>
|
||
</Popover>
|
||
`;
|
webpack/assets/javascripts/react_app/components/common/LabelIcon/index.js | ||
---|---|---|
import React from 'react';
|
||
import PropTypes from 'prop-types';
|
||
|
||
import { Popover } from '@patternfly/react-core';
|
||
import { HelpIcon } from '@patternfly/react-icons';
|
||
|
||
const LabelIcon = ({ text }) => (
|
||
<Popover bodyContent={text}>
|
||
<button
|
||
className="pf-c-form__group-label-help"
|
||
onClick={e => e.preventDefault()}
|
||
>
|
||
<HelpIcon noVerticalAlign />
|
||
</button>
|
||
</Popover>
|
||
);
|
||
|
||
LabelIcon.propTypes = {
|
||
text: PropTypes.string.isRequired,
|
||
};
|
||
|
||
export default LabelIcon;
|
webpack/assets/javascripts/react_app/components/componentRegistry.js | ||
---|---|---|
import ClipboardCopy from './common/ClipboardCopy';
|
||
import MemoryAllocationInput from './MemoryAllocationInput';
|
||
import CPUCoresInput from './CPUCoresInput';
|
||
import LabelIcon from './common/LabelIcon';
|
||
|
||
const componentRegistry = {
|
||
registry: forceSingleton('component_registry', () => ({})),
|
||
... | ... | |
{ name: 'SettingUpdateModal', type: SettingUpdateModal },
|
||
{ name: 'PersonalAccessTokens', type: PersonalAccessTokens },
|
||
{ name: 'ClipboardCopy', type: ClipboardCopy },
|
||
{ name: 'LabelIcon', type: LabelIcon },
|
||
{
|
||
name: 'MemoryAllocationInput',
|
||
type: MemoryAllocationInput,
|
webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/RegistrationCommandsPage.scss | ||
---|---|---|
.registration_commands_form {
|
||
input[type='checkbox'] {
|
||
margin: auto;
|
||
}
|
||
}
|
webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/RegistrationCommandsPageActions.js | ||
---|---|---|
import { foremanUrl } from '../../../../foreman_tools';
|
||
import { get, post } from '../../../redux/API';
|
||
|
||
import {
|
||
REGISTRATION_COMMANDS_DATA,
|
||
REGISTRATION_COMMANDS_OS_TEMPLATE,
|
||
REGISTRATION_COMMANDS,
|
||
} from '../constants';
|
||
|
||
export const dataAction = params =>
|
||
get({
|
||
key: REGISTRATION_COMMANDS_DATA,
|
||
url: foremanUrl('/hosts/register/data'),
|
||
params,
|
||
});
|
||
|
||
export const operatingSystemTemplateAction = operatingSystemId =>
|
||
get({
|
||
key: REGISTRATION_COMMANDS_OS_TEMPLATE,
|
||
url: foremanUrl(`/hosts/register/os/${operatingSystemId}`),
|
||
});
|
||
|
||
export const commandAction = params =>
|
||
post({
|
||
key: REGISTRATION_COMMANDS,
|
||
url: foremanUrl('/hosts/register'),
|
||
params,
|
||
});
|
webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/RegistrationCommandsPageHelpers.js | ||
---|---|---|
/* eslint-disable camelcase */
|
||
import React from 'react';
|
||
import { FormSelectOption } from '@patternfly/react-core';
|
||
|
||
import { foremanUrl } from '../../../../foreman_tools';
|
||
import { sprintf, translate as __ } from '../../../common/I18n';
|
||
|
||
// Form helpers
|
||
export const emptyOption = length => (
|
||
<FormSelectOption
|
||
value=""
|
||
label={length > 0 ? '' : __('Nothing to select.')}
|
||
/>
|
||
);
|
||
|
||
// OperatingSystem helpers
|
||
|
||
export const validatedOS = (operatingSystemId, template) => {
|
||
if (!operatingSystemId) {
|
||
return 'default';
|
||
}
|
||
|
||
if (template?.name) {
|
||
return 'success';
|
||
}
|
||
return 'error';
|
||
};
|
||
|
||
export const formatOSname = os => {
|
||
if (os?.minor) {
|
||
return `${os.name} ${os.major}.${os.minor}`;
|
||
}
|
||
return `${os.name} ${os.major}`;
|
||
};
|
||
|
||
export const osHelperText = (
|
||
operatingSystemId,
|
||
operatingSystems,
|
||
hostGroupId,
|
||
hostGroups,
|
||
template
|
||
) => {
|
||
if (operatingSystemId) {
|
||
return osTemplateHelperText(operatingSystemId, template);
|
||
}
|
||
|
||
if (hostGroupId) {
|
||
const osId = hostGroups.find(hg => `${hg.id}` === `${hostGroupId}`)
|
||
?.operatingsystem_id;
|
||
return (
|
||
<>
|
||
{hostGroupOSHelperText(hostGroupId, hostGroups, operatingSystems)}
|
||
<br />
|
||
{osId && osTemplateHelperText(osId, template)}
|
||
</>
|
||
);
|
||
}
|
||
|
||
return '';
|
||
};
|
||
|
||
const osTemplateHelperText = (operatingSystemId, template) => {
|
||
if (!operatingSystemId && template === undefined) {
|
||
return <> </>;
|
||
}
|
||
|
||
if (template?.name) {
|
||
return (
|
||
<span>
|
||
{__('Initial configuration template')}:{' '}
|
||
<a href={foremanUrl(template.path)} target="_blank" rel="noreferrer">
|
||
{template.name}
|
||
</a>
|
||
</span>
|
||
);
|
||
}
|
||
|
||
return (
|
||
<span className="has-error">
|
||
<a href={foremanUrl(template.os_path)} target="_blank" rel="noreferrer">
|
||
Operating system
|
||
</a>{' '}
|
||
{__('does not have assigned host_init_config template')}
|
||
</span>
|
||
);
|
||
};
|
||
|
||
const hostGroupOSHelperText = (hostGroupId, hostGroups, operatingSystems) => {
|
||
const osId = hostGroups.find(hg => `${hg.id}` === `${hostGroupId}`)
|
||
?.operatingsystem_id;
|
||
const hostGroupOS = operatingSystems.find(os => `${os.id}` === `${osId}`);
|
||
|
||
if (hostGroupOS) {
|
||
return sprintf('Host group OS: %s', formatOSname(hostGroupOS));
|
||
}
|
||
return __('No OS from host group');
|
||
};
|
webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/RegistrationCommandsPageSelectors.js | ||
---|---|---|
import {
|
||
REGISTRATION_COMMANDS_DATA,
|
||
REGISTRATION_COMMANDS_OS_TEMPLATE,
|
||
REGISTRATION_COMMANDS,
|
||
} from '../constants';
|
||
|
||
import {
|
||
selectAPIStatus,
|
||
selectAPIResponse,
|
||
} from '../../../redux/API/APISelectors';
|
||
|
||
// Form API Data
|
||
|
||
export const selectAPIStatusData = state =>
|
||
selectAPIStatus(state, REGISTRATION_COMMANDS_DATA);
|
||
|
||
export const selectOrganizations = state =>
|
||
selectAPIResponse(state, REGISTRATION_COMMANDS_DATA).organizations || [];
|
||
|
||
export const selectLocations = state =>
|
||
selectAPIResponse(state, REGISTRATION_COMMANDS_DATA).locations || [];
|
||
|
||
export const selectHostGroups = state =>
|
||
selectAPIResponse(state, REGISTRATION_COMMANDS_DATA).hostGroups || [];
|
||
|
||
export const selectOperatingSystems = state =>
|
||
selectAPIResponse(state, REGISTRATION_COMMANDS_DATA).operatingSystems || [];
|
||
|
||
export const selectOperatingSystemTemplate = state =>
|
||
selectAPIResponse(state, REGISTRATION_COMMANDS_OS_TEMPLATE).template;
|
||
|
||
export const selectSmartProxies = state =>
|
||
selectAPIResponse(state, REGISTRATION_COMMANDS_DATA).smartProxies || [];
|
||
|
||
export const selectConfigParams = state =>
|
||
selectAPIResponse(state, REGISTRATION_COMMANDS_DATA).configParams || {};
|
||
|
||
export const selectPluginData = state =>
|
||
selectAPIResponse(state, REGISTRATION_COMMANDS_DATA).pluginData || {};
|
||
|
||
// Generate Command
|
||
|
||
export const selectAPIStatusCommand = state =>
|
||
selectAPIStatus(state, REGISTRATION_COMMANDS);
|
||
|
||
export const selectCommand = state =>
|
||
selectAPIResponse(state, REGISTRATION_COMMANDS).command || '';
|
webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/__tests__/__snapshots__/integration.test.js.snap | ||
---|---|---|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||
|
||
exports[`RegistrationCommandsPage integration generate command: generated command 1`] = `
|
||
Object {
|
||
"action": Array [
|
||
Array [
|
||
Object {
|
||
"payload": Object {
|
||
"key": "REGISTRATION_COMMANDS",
|
||
"params": Object {
|
||
"hostgroupId": undefined,
|
||
"insecure": false,
|
||
"jwtExpiration": 4,
|
||
"locationId": undefined,
|
||
"operatingsystemId": undefined,
|
||
"organizationId": undefined,
|
||
"packages": "",
|
||
"repo": "",
|
||
"repoGpgKeyUrl": "",
|
||
"setupInsights": "",
|
||
"setupRemoteExecution": "",
|
||
"smartProxyId": undefined,
|
||
},
|
||
"url": "/hosts/register",
|
||
},
|
||
"type": "API_POST",
|
||
},
|
||
],
|
||
],
|
||
"state": Object {},
|
||
}
|
||
`;
|
||
|
||
exports[`RegistrationCommandsPage integration generate command: rendered 1`] = `
|
||
Object {
|
||
"action": Array [
|
||
Array [
|
||
Object {
|
||
"payload": Object {
|
||
"key": "REGISTRATION_COMMANDS_DATA",
|
||
"params": Object {
|
||
"location_id": undefined,
|
||
"organization_id": undefined,
|
||
},
|
||
"url": "/hosts/register/data",
|
||
},
|
||
"type": "API_GET",
|
||
},
|
||
],
|
||
],
|
||
"state": Object {},
|
||
}
|
||
`;
|
webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/__tests__/components/Actions.test.js | ||
---|---|---|
import { testComponentSnapshotsWithFixtures } from '../../../../../common/testHelpers';
|
||
|
||
import Actions from '../../components/Actions';
|
||
|
||
import { actionsComponentProps } from '../fixtures'
|
||
|
||
describe('RegistrationCommandsPage - Actions', () => {
|
||
testComponentSnapshotsWithFixtures(Actions, { 'renders': actionsComponentProps });
|
||
})
|
webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/__tests__/components/Advanced.test.js | ||
---|---|---|
import { testComponentSnapshotsWithFixtures } from '../../../../../common/testHelpers';
|
||
|
||
import Advanced from '../../components/Advanced';
|
||
|
||
import { advancedComponentProps } from '../fixtures'
|
||
|
||
|
||
describe('RegistrationCommandsPage - Advanced', () => {
|
||
testComponentSnapshotsWithFixtures(Advanced, { 'renders': advancedComponentProps });
|
||
})
|
webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/__tests__/components/Command.test.js | ||
---|---|---|
import { testComponentSnapshotsWithFixtures } from '../../../../../common/testHelpers';
|
||
|
||
import Command from '../../components/Command';
|
||
|
||
import { commandComponentProps } from '../fixtures'
|
||
|
||
describe('RegistrationCommandsPage - Command', () => {
|
||
testComponentSnapshotsWithFixtures(Command, { 'renders': commandComponentProps });
|
||
})
|
webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/__tests__/components/ConfigParams.test.js | ||
---|---|---|
import { testComponentSnapshotsWithFixtures } from '../../../../../common/testHelpers';
|
||
|
||
import ConfigParams from '../../components/fields/ConfigParams';
|
||
|
||
import { configParamsProps } from '../fixtures'
|
||
|
||
describe('RegistrationCommandsPage fields - ConfigParams', () => {
|
||
testComponentSnapshotsWithFixtures(ConfigParams, { 'renders': configParamsProps });
|
||
})
|
||
|
webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/__tests__/components/General.test.js | ||
---|---|---|
import { testComponentSnapshotsWithFixtures } from '../../../../../common/testHelpers';
|
||
|
||
import General from '../../components/General';
|
||
|
||
import { generalComponentProps } from '../fixtures'
|
||
|
||
describe('RegistrationCommandsPage - General', () => {
|
||
testComponentSnapshotsWithFixtures(General, { 'renders': generalComponentProps });
|
||
})
|
webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/__tests__/components/HostGroup.test.js | ||
---|---|---|
import { testComponentSnapshotsWithFixtures } from '../../../../../common/testHelpers';
|
||
|
||
import HostGroup from '../../components/fields/HostGroup';
|
||
|
||
import { hostGroupProps } from '../fixtures'
|
||
|
||
describe('RegistrationCommandsPage fields - HostGroup', () => {
|
||
testComponentSnapshotsWithFixtures(HostGroup, { 'renders': hostGroupProps });
|
||
})
|
||
|
webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/__tests__/components/Insecure.test.js | ||
---|---|---|
import { testComponentSnapshotsWithFixtures } from '../../../../../common/testHelpers';
|
||
|
||
import Insecure from '../../components/fields/Insecure';
|
||
|
||
import { insecureProps } from '../fixtures'
|
||
|
||
describe('RegistrationCommandsPage fields - Insecure', () => {
|
||
testComponentSnapshotsWithFixtures(Insecure, { 'renders': insecureProps });
|
||
})
|
||
|
webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/__tests__/components/OperatingSystem.test.js | ||
---|---|---|
import { testComponentSnapshotsWithFixtures } from '../../../../../common/testHelpers';
|
||
|
||
import OperatingSystem from '../../components/fields/OperatingSystem';
|
||
|
||
import { osProps } from '../fixtures'
|
||
|
||
jest.mock('react-redux');
|
||
|
||
describe('RegistrationCommandsPage fields - OperatingSystem', () => {
|
||
testComponentSnapshotsWithFixtures(OperatingSystem, { 'renders': osProps });
|
||
})
|
||
|
webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/__tests__/components/Packages.test.js | ||
---|---|---|
import { testComponentSnapshotsWithFixtures } from '../../../../../common/testHelpers';
|
||
|
||
import Packages from '../../components/fields/Packages';
|
||
|
||
import { packagesProps } from '../fixtures'
|
||
|
||
describe('RegistrationCommandsPage fields - Packages', () => {
|
||
testComponentSnapshotsWithFixtures(Packages, { 'renders': packagesProps });
|
||
})
|
||
|
webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/__tests__/components/Repository.test.js | ||
---|---|---|
import { testComponentSnapshotsWithFixtures } from '../../../../../common/testHelpers';
|
||
|
||
import Repository from '../../components/fields/Repository';
|
||
|
||
import { repositoryProps } from '../fixtures'
|
||
|
||
describe('RegistrationCommandsPage fields - Repository', () => {
|
||
testComponentSnapshotsWithFixtures(Repository, { 'renders': repositoryProps });
|
||
})
|
||
|
webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/__tests__/components/SmartProxy.test.js | ||
---|---|---|
import { testComponentSnapshotsWithFixtures } from '../../../../../common/testHelpers';
|
||
|
||
import SmartProxy from '../../components/fields/SmartProxy';
|
||
|
||
import { smartProxyProps } from '../fixtures'
|
||
|
||
describe('RegistrationCommandsPage fields - SmartProxy', () => {
|
||
testComponentSnapshotsWithFixtures(SmartProxy, { 'renders': smartProxyProps });
|
||
})
|
||
|
webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/__tests__/components/Taxonomies.test.js | ||
---|---|---|
import { testComponentSnapshotsWithFixtures } from '../../../../../common/testHelpers';
|
||
|
||
import Taxonomies from '../../components/fields/Taxonomies';
|
||
|
||
import { taxonomiesProps } from '../fixtures'
|
||
|
||
describe('RegistrationCommandsPage fields - Taxonomies', () => {
|
||
testComponentSnapshotsWithFixtures(Taxonomies, { 'renders': taxonomiesProps });
|
||
})
|
||
|
webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/__tests__/components/TokenLifeTime.test.js | ||
---|---|---|
import { testComponentSnapshotsWithFixtures } from '../../../../../common/testHelpers';
|
||
|
||
import TokenLifeTime from '../../components/fields/TokenLifeTime';
|
||
|
||
import { tokenLifeTimeProps } from '../fixtures'
|
||
|
||
describe('RegistrationCommandsPage fields - TokenLifeTime', () => {
|
||
testComponentSnapshotsWithFixtures(TokenLifeTime, { 'renders': tokenLifeTimeProps });
|
||
})
|
||
|
webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/__tests__/components/__snapshots__/Actions.test.js.snap | ||
---|---|---|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||
|
||
exports[`RegistrationCommandsPage - Actions renders 1`] = `
|
||
<Fragment>
|
||
<ActionGroup>
|
||
<Button
|
||
id="generate_btn"
|
||
isDisabled={false}
|
||
isLoading={false}
|
||
onClick={[Function]}
|
||
variant="primary"
|
||
>
|
||
Generate
|
||
</Button>
|
||
<Link
|
||
to="/hosts"
|
||
>
|
||
<Button
|
||
variant="link"
|
||
>
|
||
Cancel
|
||
</Button>
|
||
</Link>
|
||
</ActionGroup>
|
||
<FormGroup
|
||
fieldId="actions_help"
|
||
>
|
||
<FormHelperText
|
||
icon={
|
||
<ExclamationCircleIcon
|
||
color="currentColor"
|
||
noVerticalAlign={false}
|
||
size="sm"
|
||
/>
|
||
}
|
||
isHidden={true}
|
||
/>
|
||
</FormGroup>
|
||
</Fragment>
|
||
`;
|
webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/__tests__/components/__snapshots__/Advanced.test.js.snap | ||
---|---|---|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||
|
||
exports[`RegistrationCommandsPage - Advanced renders 1`] = `
|
||
<Fragment>
|
||
<ConfigParams
|
||
configParams={Object {}}
|
||
handleInsights={[Function]}
|
||
handleRemoteExecution={[Function]}
|
||
isLoading={false}
|
||
setupInsights=""
|
||
setupRemoteExecution=""
|
||
/>
|
||
<Packages
|
||
configParams={Object {}}
|
||
handlePackages={[Function]}
|
||
isLoading={false}
|
||
packages=""
|
||
/>
|
||
<Repository
|
||
handleRepo={[Function]}
|
||
handleRepoGpgKeyUrl={[Function]}
|
||
isLoading={false}
|
||
repo=""
|
||
repoGpgKeyUrl=""
|
||
/>
|
||
<TokenLifeTime
|
||
handleInvalidField={[Function]}
|
||
isLoading={false}
|
||
onChange={[Function]}
|
||
value=""
|
||
/>
|
||
</Fragment>
|
||
`;
|
webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/__tests__/components/__snapshots__/Command.test.js.snap | ||
---|---|---|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||
|
||
exports[`RegistrationCommandsPage - Command renders 1`] = `
|
||
<FormGroup
|
||
label="Registration command"
|
||
>
|
||
<ClipboardCopy
|
||
clickTip="Successfully copied to clipboard!"
|
||
entryDelay={100}
|
||
exitDelay={1600}
|
||
hoverTip="Copy to clipboard"
|
||
isCode={true}
|
||
isExpanded={true}
|
||
isReadOnly={true}
|
||
maxWidth="150px"
|
||
onChange={[Function]}
|
||
onCopy={[Function]}
|
||
position="top"
|
||
switchDelay={2000}
|
||
textAriaLabel="Copyable input"
|
||
toggleAriaLabel="Show content"
|
||
variant="expansion"
|
||
>
|
||
command
|
||
</ClipboardCopy>
|
||
</FormGroup>
|
||
`;
|
webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/__tests__/components/__snapshots__/ConfigParams.test.js.snap | ||
---|---|---|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||
|
||
exports[`RegistrationCommandsPage fields - ConfigParams renders 1`] = `
|
||
<Fragment>
|
||
<FormGroup
|
||
fieldId="registration_setup_remote_execution"
|
||
isRequired={true}
|
||
label="Setup REX"
|
||
labelIcon={
|
||
<LabelIcon
|
||
text="Setup remote execution. If set to \`Yes\`, SSH keys will be installed on the registered host. The inherited value is based on the \`host_registration_remote_execution\` parameter. It can be inherited e.g. from host group, operating system, organization. When overridden, the selected value will be stored on host parameter level."
|
||
/>
|
||
}
|
||
>
|
||
<FormSelect
|
||
className="without_select2"
|
||
id="registration_setup_remote_execution"
|
||
isDisabled={false}
|
||
isRequired={true}
|
||
onBlur={[Function]}
|
||
onChange={[Function]}
|
||
onFocus={[Function]}
|
||
ouiaSafe={true}
|
||
validated="default"
|
||
value=""
|
||
>
|
||
<FormSelectOption
|
||
key="0"
|
||
label="Inherit from host parameter (no)"
|
||
value=""
|
||
/>
|
||
<FormSelectOption
|
||
key="1"
|
||
label="Yes (override)"
|
||
value={true}
|
||
/>
|
||
<FormSelectOption
|
||
key="2"
|
||
label="No (override)"
|
||
value={false}
|
||
/>
|
||
</FormSelect>
|
||
</FormGroup>
|
||
<FormGroup
|
||
fieldId="registration_setup_insights"
|
||
isRequired={true}
|
||
label="Setup Insights"
|
||
labelIcon={
|
||
<LabelIcon
|
||
text="If set to \`Yes\`, Insights client will be installed and registered on Red Hat family operating systems. It has no effect on other OS families that do not support it. The inherited value is based on the \`host_registration_insights\` parameter. It can be inherited e.g. from host group, operating system, organization. When overridden, the selected value will be stored on host parameter level."
|
||
/>
|
||
}
|
||
>
|
||
<FormSelect
|
||
className="without_select2"
|
||
id="registration_setup_insights"
|
||
isDisabled={false}
|
||
isRequired={true}
|
||
onBlur={[Function]}
|
||
onChange={[Function]}
|
||
onFocus={[Function]}
|
||
ouiaSafe={true}
|
||
validated="default"
|
||
value=""
|
||
>
|
||
<FormSelectOption
|
||
key="0"
|
||
label="Inherit from host parameter (no)"
|
||
value=""
|
||
/>
|
||
<FormSelectOption
|
||
key="1"
|
||
label="Yes (override)"
|
||
value={true}
|
||
/>
|
||
<FormSelectOption
|
||
key="2"
|
||
label="No (override)"
|
||
value={false}
|
||
/>
|
||
</FormSelect>
|
||
</FormGroup>
|
||
</Fragment>
|
||
`;
|
webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/__tests__/components/__snapshots__/General.test.js.snap | ||
---|---|---|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||
|
||
exports[`RegistrationCommandsPage - General renders 1`] = `
|
||
<Fragment>
|
||
<Taxonomies
|
||
handleLocation={[Function]}
|
||
handleOrganization={[Function]}
|
||
isLoading={false}
|
||
locationId={0}
|
||
locations={Array []}
|
||
organizationId={0}
|
||
organizations={Array []}
|
||
/>
|
||
<HostGroup
|
||
handleHostGroup={[Function]}
|
||
hostGroupId={0}
|
||
hostGroups={Array []}
|
||
isLoading={false}
|
||
/>
|
||
<OperatingSystem
|
||
handleInvalidField={[Function]}
|
||
handleOperatingSystem={[Function]}
|
||
hostGroupId={0}
|
||
hostGroups={Array []}
|
||
isLoading={false}
|
||
operatingSystemId={0}
|
||
operatingSystemTemplate=""
|
||
operatingSystems={Array []}
|
||
/>
|
||
<SmartProxy
|
||
handleSmartProxy={[Function]}
|
||
isLoading={false}
|
||
smartProxies={Array []}
|
||
smartProxyId={0}
|
||
/>
|
||
<Insecure
|
||
handleInsecure={[Function]}
|
||
insecure={false}
|
||
isLoading={false}
|
||
/>
|
||
</Fragment>
|
||
`;
|
webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/__tests__/components/__snapshots__/HostGroup.test.js.snap | ||
---|---|---|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||
|
||
exports[`RegistrationCommandsPage fields - HostGroup renders 1`] = `
|
||
<FormGroup
|
||
fieldId="reg_host_group"
|
||
label="Host group"
|
||
>
|
||
<FormSelect
|
||
className="without_select2"
|
||
id="reg_host_group"
|
||
isDisabled={false}
|
||
isRequired={false}
|
||
onBlur={[Function]}
|
||
onChange={[Function]}
|
||
onFocus={[Function]}
|
||
ouiaSafe={true}
|
||
validated="default"
|
||
value={0}
|
||
>
|
||
<FormSelectOption
|
||
label=""
|
||
value=""
|
||
/>
|
||
<FormSelectOption
|
||
key="0"
|
||
label="test_hg"
|
||
value={0}
|
||
/>
|
||
</FormSelect>
|
||
</FormGroup>
|
||
`;
|
webpack/assets/javascripts/react_app/routes/RegistrationCommands/RegistrationCommandsPage/__tests__/components/__snapshots__/Insecure.test.js.snap | ||
---|---|---|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||
|
||
exports[`RegistrationCommandsPage fields - Insecure renders 1`] = `
|
||
<FormGroup
|
||
fieldId="reg_insecure"
|
||
>
|
||
<Checkbox
|
||
className=""
|
||
id="reg_insecure"
|
||
isChecked={false}
|
||
isDisabled={false}
|
||
isValid={true}
|
||
label={
|
||
<span>
|
||
Insecure
|
||
|
||
<LabelIcon
|
Also available in: Unified diff
Fixes #31240 - New Host Registration Form (#8419)
Completely in React, with router & PF4 components
Divided into two tabs: General fields & Advanced Fields
Slots for extending form fields (general / advanced)
Form can be submitted only if there are no invalid fields
Related plugin extensions:
Changes:Katello/katello#9249
theforeman/foreman_remote_execution#574
changing ORG/LOC will fetch new data and reset form fields (HostGroup, OS & Smart Proxy)
Reset of fields from plugins is handled by plugins.
If selected, following fields inherit the value from selected host group: Operating System, Activation Keys & Life Cycle Environment
Selecting HG resets OS field
When selected, show info about assigned host_init_config template.
If template is not found, show error and block form
organization -> location -> operatingsystem -> hostgroup
Install packages after the host registration
Can be set to unlimited, otherwise value validated as: >= 1 && <= 999 999