foreman_ansible 6.4.0 → 7.0.2
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/app/controllers/api/v2/ansible_inventories_controller.rb +1 -1
- data/app/graphql/mutations/ansible_variable_overrides/create.rb +26 -0
- data/app/graphql/mutations/ansible_variable_overrides/delete.rb +38 -0
- data/app/graphql/mutations/ansible_variable_overrides/update.rb +26 -0
- data/app/graphql/mutations/hosts/assign_ansible_roles.rb +37 -0
- data/app/graphql/presenters/ansible_role_presenter.rb +12 -0
- data/app/graphql/presenters/overriden_ansible_variable_presenter.rb +19 -0
- data/app/graphql/resolvers/ansible_role/path.rb +11 -0
- data/app/graphql/resolvers/ansible_variable/path.rb +11 -0
- data/app/graphql/types/ansible_role.rb +10 -0
- data/app/graphql/types/ansible_variable.rb +24 -0
- data/app/graphql/types/ansible_variable_override.rb +9 -0
- data/app/graphql/types/inherited_ansible_role.rb +13 -0
- data/app/graphql/types/overriden_ansible_variable.rb +27 -0
- data/app/helpers/foreman_ansible/ansible_roles_data_preparations.rb +22 -22
- data/app/models/concerns/foreman_ansible/host_managed_extensions.rb +23 -4
- data/app/models/concerns/foreman_ansible/hostgroup_extensions.rb +2 -1
- data/app/models/foreman_ansible/ansible_provider.rb +8 -6
- data/app/services/foreman_ansible/ansible_report_importer.rb +2 -6
- data/app/services/foreman_ansible/inventory_creator.rb +1 -1
- data/app/services/foreman_ansible/override_resolver.rb +22 -0
- data/app/views/api/v2/ansible_override_values/index.json.rabl +3 -0
- data/app/views/api/v2/ansible_variables/show.json.rabl +1 -1
- data/app/views/foreman_ansible/ansible_roles/_hostgroup_ansible_roles_button.erb +3 -0
- data/app/views/foreman_ansible/job_templates/convert_to_rhel.erb +6 -2
- data/app/views/foreman_ansible/job_templates/run_openscap_scans_-_ansible_default.erb +20 -0
- data/config/routes.rb +3 -0
- data/db/migrate/20210818083407_fix_ansible_setting_category_to_dsl.rb +5 -0
- data/lib/foreman_ansible/engine.rb +1 -17
- data/lib/foreman_ansible/register.rb +115 -4
- data/lib/foreman_ansible/version.rb +1 -1
- data/package.json +4 -2
- data/test/functional/api/v2/ansible_inventories_controller_test.rb +1 -2
- data/test/graphql/mutations/hosts/assign_ansible_roles_mutation_test.rb +96 -0
- data/test/graphql/queries/ansible_roles_query_test.rb +35 -0
- data/test/unit/ansible_provider_test.rb +3 -6
- data/test/unit/concerns/host_managed_extensions_test.rb +8 -0
- data/test/unit/concerns/hostgroup_extensions_test.rb +6 -0
- data/test/unit/hostgroup_ansible_role_test.rb +13 -0
- data/test/unit/services/override_resolver_test.rb +34 -0
- data/webpack/components/AnsibleHostDetail/AnsibleHostDetail.js +52 -27
- data/webpack/components/AnsibleHostDetail/AnsibleHostDetail.scss +5 -1
- data/webpack/components/AnsibleHostDetail/AnsibleHostDetail.test.js +12 -6
- data/webpack/components/AnsibleHostDetail/components/AnsibleHostInventory/AnsibleHostInventory.js +22 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleHostInventory/AnsibleHostInventory.scss +4 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleHostInventory/AnsibleHostInventory.test.js +104 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleHostInventory/index.js +38 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/AnsibleVariableOverrides.scss +3 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/AnsibleVariableOverridesTable.js +240 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/AnsibleVariableOverridesTableHelper.js +111 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/EditableAction.js +161 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/EditableAction.scss +7 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/EditableActionHelper.js +49 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/EditableValue.js +70 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/EditableValueHelper.js +35 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/__test__/AnsibleVariableOverrides.fixtures.js +438 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/__test__/AnsibleVariableOverrides.test.js +71 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/__test__/AnsibleVariableOverridesDelete.test.js +74 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/__test__/AnsibleVariableOverridesUpdate.test.js +188 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/index.js +61 -0
- data/webpack/components/AnsibleHostDetail/components/JobsTab/JobsTabHelper.js +79 -0
- data/webpack/components/AnsibleHostDetail/components/JobsTab/NewRecurringJobHelper.js +106 -0
- data/webpack/components/AnsibleHostDetail/components/JobsTab/NewRecurringJobModal.js +129 -0
- data/webpack/components/AnsibleHostDetail/components/JobsTab/NewRecurringJobModal.scss +7 -0
- data/webpack/components/AnsibleHostDetail/components/JobsTab/PreviousJobsTable.js +103 -0
- data/webpack/components/AnsibleHostDetail/components/JobsTab/RecurringJobsTable.js +96 -0
- data/webpack/components/AnsibleHostDetail/components/JobsTab/__test__/JobsTab.fixtures.js +184 -0
- data/webpack/components/AnsibleHostDetail/components/JobsTab/__test__/JobsTab.test.js +195 -0
- data/webpack/components/AnsibleHostDetail/components/JobsTab/index.js +88 -0
- data/webpack/components/AnsibleHostDetail/components/RolesTab/AllRolesModal/AllRolesTable.js +89 -0
- data/webpack/components/AnsibleHostDetail/components/RolesTab/AllRolesModal/index.js +74 -0
- data/webpack/components/AnsibleHostDetail/components/RolesTab/EditRolesModal/EditRolesForm.js +90 -0
- data/webpack/components/AnsibleHostDetail/components/RolesTab/EditRolesModal/EditRolesModal.scss +3 -0
- data/webpack/components/AnsibleHostDetail/components/RolesTab/EditRolesModal/EditRolesModalHelper.js +40 -0
- data/webpack/components/AnsibleHostDetail/components/RolesTab/EditRolesModal/index.js +85 -0
- data/webpack/components/AnsibleHostDetail/components/RolesTab/RolesTable.js +131 -0
- data/webpack/components/AnsibleHostDetail/components/RolesTab/__test__/EditRoles.test.js +85 -0
- data/webpack/components/AnsibleHostDetail/components/RolesTab/__test__/RolesTab.fixtures.js +191 -0
- data/webpack/components/AnsibleHostDetail/components/RolesTab/__test__/RolesTab.test.js +79 -0
- data/webpack/components/AnsibleHostDetail/components/RolesTab/index.js +75 -0
- data/webpack/components/AnsibleHostDetail/components/SecondaryTabRoutes.js +60 -0
- data/webpack/components/AnsibleHostDetail/components/TabLayout.js +12 -0
- data/webpack/components/AnsibleHostDetail/constants.js +9 -0
- data/webpack/components/AnsibleHostDetail/helpers.js +4 -0
- data/webpack/components/AnsibleRolesAndVariables/__test__/AnsibleRolesAndVariablesImport.test.js +15 -10
- data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRole.js +29 -0
- data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRole.test.js +3 -0
- data/webpack/components/AnsibleRolesSwitcher/components/AvailableRolesList.js +2 -1
- data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AnsibleRole.test.js.snap +3 -3
- data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AvailableRolesList.test.js.snap +4 -0
- data/webpack/components/DualList/DualList.scss +3 -0
- data/webpack/components/DualList/ListControls.js +65 -0
- data/webpack/components/DualList/ListHeader.js +16 -0
- data/webpack/components/DualList/ListItem.js +69 -0
- data/webpack/components/DualList/ListPane.js +95 -0
- data/webpack/components/DualList/SelectedStatus.js +21 -0
- data/webpack/components/DualList/index.js +103 -0
- data/webpack/components/ErrorState.js +16 -0
- data/webpack/components/withLoading.js +135 -0
- data/webpack/components/withPagination.js +0 -0
- data/webpack/formHelper.js +131 -0
- data/webpack/globalIdHelper.js +13 -0
- data/webpack/global_index.js +7 -1
- data/webpack/graphql/mutations/assignAnsibleRoles.gql +17 -0
- data/webpack/graphql/mutations/cancelRecurringLogic.gql +12 -0
- data/webpack/graphql/mutations/createAnsibleVariableOverride.gql +28 -0
- data/webpack/graphql/mutations/createJobInvocation.gql +11 -0
- data/webpack/graphql/mutations/deleteAnsibleVariableOverride.gql +17 -0
- data/webpack/graphql/mutations/updateAnsibleVariableOverride.gql +29 -0
- data/webpack/graphql/queries/allAnsibleRoles.gql +13 -0
- data/webpack/graphql/queries/ansibleRoles.gql +13 -0
- data/webpack/graphql/queries/currentUserAttributes.gql +11 -0
- data/webpack/graphql/queries/hostAnsibleRoles.gql +18 -0
- data/webpack/graphql/queries/hostAvailableAnsibleRoles.gql +11 -0
- data/webpack/graphql/queries/hostVariableOverrides.gql +40 -0
- data/webpack/graphql/queries/recurringJobs.gql +28 -0
- data/webpack/helpers/pageParamsHelper.js +40 -0
- data/webpack/helpers/paginationHelper.js +9 -0
- data/webpack/permissionsHelper.js +58 -0
- data/webpack/routes/HostgroupJobs/__test__/HostgroupJobs.fixtures.js +63 -0
- data/webpack/routes/HostgroupJobs/__test__/HostgroupJobs.test.js +112 -0
- data/webpack/routes/HostgroupJobs/index.js +26 -0
- data/webpack/routes/routes.js +10 -0
- data/webpack/testHelper.js +165 -0
- data/webpack/toastHelper.js +4 -0
- metadata +129 -54
- data/app/assets/images/foreman_ansible/Ansible.png +0 -0
- data/app/models/foreman_ansible/fact_name.rb +0 -16
- data/app/models/setting/ansible.rb +0 -106
- data/app/services/foreman_ansible/fact_importer.rb +0 -99
- data/app/services/foreman_ansible/fact_parser.rb +0 -126
- data/app/services/foreman_ansible/fact_sparser.rb +0 -37
- data/app/services/foreman_ansible/operating_system_parser.rb +0 -102
- data/app/services/foreman_ansible/structured_fact_importer.rb +0 -25
- data/test/unit/services/fact_importer_test.rb +0 -52
- data/test/unit/services/fact_parser_test.rb +0 -281
- data/test/unit/services/fact_sparser_test.rb +0 -24
- data/test/unit/services/structured_fact_importer_test.rb +0 -30
- data/webpack/components/AnsibleRolesAndVariables/__test__/__snapshots__/AnsibleRolesAndVariablesImport.test.js.snap +0 -177
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 299049c29764a0920259664c06288f37ea56d4b920e049243baeab9ad7f2e608
|
|
4
|
+
data.tar.gz: 779264101df1f9fa6e0188c8673a435b98eb4dbd9fd814e754f991247b5bb250
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '08a1b935eb0c033ff08674e4922ee597d39ed602ef351b82d9ac763af9d850e5a32ff9ea482af7f74a641552ebaf62094b6fa59170cba317b5bba67949d31a8d'
|
|
7
|
+
data.tar.gz: 3f814381b2167e370757f761a0b5d3e1217e3c3ba4293d7f1ecf1e77599c232ef8c62beae293c8593d81ab4e305ae1cced983527bc6d29e248bbda3a3f4e731e
|
|
@@ -90,7 +90,7 @@ module Api
|
|
|
90
90
|
private
|
|
91
91
|
|
|
92
92
|
def schedule_params
|
|
93
|
-
template_name = Setting
|
|
93
|
+
template_name = Setting['ansible_inventory_template']
|
|
94
94
|
@report_template = ReportTemplate.find_by!(:name => template_name)
|
|
95
95
|
params[:id] = @report_template.id
|
|
96
96
|
params[:report_format] = 'json' if params[:report_format].blank?
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Mutations
|
|
2
|
+
module AnsibleVariableOverrides
|
|
3
|
+
class Create < ::Mutations::CreateMutation
|
|
4
|
+
graphql_name 'CreateAnsibleVariableOverrideMutation'
|
|
5
|
+
description 'Creates Ansible Variable Override'
|
|
6
|
+
|
|
7
|
+
resource_class LookupValue
|
|
8
|
+
|
|
9
|
+
argument :host_id, Int, required: true
|
|
10
|
+
argument :lookup_key_id, Int, required: true
|
|
11
|
+
argument :value, ::Types::RawJson, required: true
|
|
12
|
+
argument :match, String, required: true
|
|
13
|
+
argument :omit, Boolean
|
|
14
|
+
|
|
15
|
+
field :overriden_ansible_variable, ::Types::OverridenAnsibleVariable, :null => true
|
|
16
|
+
|
|
17
|
+
def resolve(host_id:, **kwargs)
|
|
18
|
+
result = super kwargs
|
|
19
|
+
host = Host.find host_id
|
|
20
|
+
vars = AnsibleVariable.where :id => kwargs[:lookup_key_id]
|
|
21
|
+
resolver = ::ForemanAnsible::OverrideResolver.new(host, vars)
|
|
22
|
+
result.merge :overriden_ansible_variable => ::Presenters::OverridenAnsibleVariablePresenter.new(vars.first, resolver)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Mutations
|
|
2
|
+
module AnsibleVariableOverrides
|
|
3
|
+
class Delete < ::Mutations::DeleteMutation
|
|
4
|
+
graphql_name 'DeleteAnsibleVariableOverride'
|
|
5
|
+
description 'Deletes Ansible Variable Override'
|
|
6
|
+
|
|
7
|
+
resource_class LookupValue
|
|
8
|
+
|
|
9
|
+
argument :host_id, Int, required: true
|
|
10
|
+
argument :variable_id, Int, required: true
|
|
11
|
+
|
|
12
|
+
field :overriden_ansible_variable, ::Types::OverridenAnsibleVariable, :null => true
|
|
13
|
+
|
|
14
|
+
def resolve(id:, host_id:, variable_id:)
|
|
15
|
+
host = Host.find_by :id => host_id
|
|
16
|
+
variable = AnsibleVariable.find_by :id => variable_id
|
|
17
|
+
return resource_not_found(_('Host not found by id: %s'), host_id) unless host
|
|
18
|
+
return resource_not_found(_('Ansible Variable not found by id: %s'), variable_id) unless variable
|
|
19
|
+
authorize!(host, :view)
|
|
20
|
+
authorize!(variable, :edit)
|
|
21
|
+
|
|
22
|
+
result = super id: id
|
|
23
|
+
resolver = ::ForemanAnsible::OverrideResolver.new(host, [variable.id])
|
|
24
|
+
result.merge :overriden_ansible_variable => ::Presenters::OverridenAnsibleVariablePresenter.new(variable, resolver)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def resource_not_found(message)
|
|
28
|
+
{
|
|
29
|
+
:overriden_ansible_variable => nil,
|
|
30
|
+
:errros => [{
|
|
31
|
+
:path => ['base'],
|
|
32
|
+
:message => message
|
|
33
|
+
}]
|
|
34
|
+
}
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Mutations
|
|
2
|
+
module AnsibleVariableOverrides
|
|
3
|
+
class Update < ::Mutations::UpdateMutation
|
|
4
|
+
graphql_name 'UpdateAnsibleVariableOverrideMutation'
|
|
5
|
+
description 'Updates Ansible Variable Override'
|
|
6
|
+
|
|
7
|
+
resource_class LookupValue
|
|
8
|
+
|
|
9
|
+
argument :value, ::Types::RawJson, required: true
|
|
10
|
+
argument :match, String, required: false
|
|
11
|
+
argument :omit, Boolean, required: false
|
|
12
|
+
argument :host_id, Int, required: true
|
|
13
|
+
argument :ansible_variable_id, Int, required: true
|
|
14
|
+
|
|
15
|
+
field :overriden_ansible_variable, ::Types::OverridenAnsibleVariable, :null => true
|
|
16
|
+
|
|
17
|
+
def resolve(host_id:, ansible_variable_id:, **kwargs)
|
|
18
|
+
result = super kwargs
|
|
19
|
+
host = Host.find host_id
|
|
20
|
+
vars = AnsibleVariable.where :id => ansible_variable_id
|
|
21
|
+
resolver = ::ForemanAnsible::OverrideResolver.new(host, vars.pluck(:id))
|
|
22
|
+
result.merge :overriden_ansible_variable => ::Presenters::OverridenAnsibleVariablePresenter.new(vars.first, resolver)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Mutations
|
|
2
|
+
module Hosts
|
|
3
|
+
class AssignAnsibleRoles < ::Mutations::UpdateMutation
|
|
4
|
+
resource_class Host::Managed
|
|
5
|
+
|
|
6
|
+
argument :ansible_role_ids, [Integer], required: true
|
|
7
|
+
|
|
8
|
+
field :host, Types::Host, 'The updated host.', null: false
|
|
9
|
+
|
|
10
|
+
def resolve(id:, ansible_role_ids:)
|
|
11
|
+
host = load_object_by(id: id)
|
|
12
|
+
authorize!(host, :edit)
|
|
13
|
+
|
|
14
|
+
existing = host.host_ansible_roles
|
|
15
|
+
updated_ids = []
|
|
16
|
+
attrs = []
|
|
17
|
+
|
|
18
|
+
ansible_role_ids.each do |role_id|
|
|
19
|
+
current = existing.find_by :ansible_role_id => role_id
|
|
20
|
+
attrs << { :id => current&.id, :position => attrs.count + 1, :ansible_role_id => role_id }
|
|
21
|
+
updated_ids << current.id if current
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
existing.where.not(:id => updated_ids).each do |item|
|
|
25
|
+
attrs << { :id => item.id, :position => attrs.count + 1, :_destroy => true }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
host.host_ansible_roles_attributes = attrs
|
|
29
|
+
save_object(host)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def result_key
|
|
33
|
+
:host
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module Presenters
|
|
2
|
+
class AnsibleRolePresenter
|
|
3
|
+
attr_reader :ansible_role, :inherited
|
|
4
|
+
|
|
5
|
+
delegate :id, :name, :association, :to => :ansible_role
|
|
6
|
+
|
|
7
|
+
def initialize(ansible_role, inherited)
|
|
8
|
+
@ansible_role = ansible_role
|
|
9
|
+
@inherited = inherited
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Presenters
|
|
2
|
+
class OverridenAnsibleVariablePresenter
|
|
3
|
+
attr_reader :ansible_variable
|
|
4
|
+
|
|
5
|
+
delegate :id, :key, :description, :override?,
|
|
6
|
+
:parameter_type, :hidden_value?, :omit, :required,
|
|
7
|
+
:validator_type, :validator_rule, :default_value,
|
|
8
|
+
:ansible_role, :current_value, :to => :ansible_variable
|
|
9
|
+
|
|
10
|
+
def initialize(ansible_variable, override_resolver)
|
|
11
|
+
@ansible_variable = ansible_variable
|
|
12
|
+
@override_resolver = override_resolver
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def current_value
|
|
16
|
+
@override_resolver.resolve @ansible_variable
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Types
|
|
2
|
+
class AnsibleVariable < BaseObject
|
|
3
|
+
description 'Ansible Variable'
|
|
4
|
+
|
|
5
|
+
global_id_field :id
|
|
6
|
+
|
|
7
|
+
field :key, String
|
|
8
|
+
field :path, resolver: Resolvers::AnsibleVariable::Path
|
|
9
|
+
field :override, Boolean
|
|
10
|
+
field :description, String
|
|
11
|
+
field :hidden_value, Boolean
|
|
12
|
+
field :parameter_type, String
|
|
13
|
+
field :omit, Boolean
|
|
14
|
+
field :required, Boolean
|
|
15
|
+
field :validator_type, String
|
|
16
|
+
field :validator_rule, String
|
|
17
|
+
field :default_value, ::Types::RawJson
|
|
18
|
+
field :ansible_role_name, String
|
|
19
|
+
|
|
20
|
+
def ansible_role_name
|
|
21
|
+
object.ansible_role.name
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
module Types
|
|
2
|
+
class AnsibleVariableOverride < GraphQL::Types::Relay::BaseObject
|
|
3
|
+
description 'Override value for Ansible Variable'
|
|
4
|
+
|
|
5
|
+
field :value, ::Types::RawJson, :null => false
|
|
6
|
+
field :element, ::Types::RawJson, :null => false
|
|
7
|
+
field :element_name, ::Types::RawJson, :null => false
|
|
8
|
+
end
|
|
9
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Types
|
|
2
|
+
class OverridenAnsibleVariable < ::Types::AnsibleVariable
|
|
3
|
+
description 'Ansible Variable with an override value for a host'
|
|
4
|
+
model_class ::AnsibleVariable
|
|
5
|
+
|
|
6
|
+
field :current_value, ::Types::AnsibleVariableOverride, :null => true
|
|
7
|
+
field :lookup_values, ::Types::LookupValue.connection_type do
|
|
8
|
+
argument :match, String, required: false
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
field :meta, ::Types::Meta, resolve: (proc do |object|
|
|
12
|
+
{
|
|
13
|
+
:can_edit => ::User.current.can?(object.ansible_variable.permission_name(:edit), object.ansible_variable),
|
|
14
|
+
:can_destroy => ::User.current.can?(object.ansible_variable.permission_name(:destroy), object.ansible_variable)
|
|
15
|
+
}
|
|
16
|
+
end)
|
|
17
|
+
|
|
18
|
+
def lookup_values(match: nil)
|
|
19
|
+
return CollectionLoader.for(object.ansible_variable.class, :lookup_values).load(object.ansible_variable) unless match
|
|
20
|
+
|
|
21
|
+
scope = lambda do |sc|
|
|
22
|
+
sc.where(:match => match)
|
|
23
|
+
end
|
|
24
|
+
CollectionLoader.for(object.ansible_variable.class, :lookup_values, scope).load(object.ansible_variable)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -2,22 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
module ForemanAnsible
|
|
4
4
|
module AnsibleRolesDataPreparations
|
|
5
|
-
VARIABLE_ACTION_NAMES = { 'new' =>
|
|
6
|
-
ROLE_ACTION_NAMES = { 'new' =>
|
|
5
|
+
VARIABLE_ACTION_NAMES = { 'new' => _('Add'), 'obsolete' => _('Remove'), 'update' => _('Update') }.freeze
|
|
6
|
+
ROLE_ACTION_NAMES = { 'new' => _('Import Role'), 'obsolete' => _('Remove Role'), 'old' => _('Update Role Variables') }.freeze
|
|
7
7
|
|
|
8
|
-
def
|
|
9
|
-
|
|
8
|
+
def variable_action_name(kind)
|
|
9
|
+
VARIABLE_ACTION_NAMES[kind]
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
def
|
|
13
|
-
|
|
12
|
+
def role_action_name(kind)
|
|
13
|
+
ROLE_ACTION_NAMES[kind]
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def get_old_roles_variables(imported_variables, role)
|
|
17
|
-
variables = { '
|
|
17
|
+
variables = { 'new' => [], 'obsolete' => [], 'update' => [] }
|
|
18
18
|
imported_variables.each do |kind, temp_variables|
|
|
19
19
|
temp_variables.each do |temp_variable|
|
|
20
|
-
variables[
|
|
20
|
+
variables[kind].append(temp_variable.key) if temp_variable.ansible_role_id == role.id
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
23
|
variables
|
|
@@ -26,16 +26,16 @@ module ForemanAnsible
|
|
|
26
26
|
def variables_to_s(variables)
|
|
27
27
|
str = ''
|
|
28
28
|
variables.each do |action, temp_variables|
|
|
29
|
-
str += "#{action}: #{temp_variables.size}, " unless temp_variables.empty?
|
|
29
|
+
str += "#{variable_action_name action}: #{temp_variables.size}, " unless temp_variables.empty?
|
|
30
30
|
end
|
|
31
31
|
str[0..-3]
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
def get_roles_variables(imported_variables, variables_importer, kind, role)
|
|
35
35
|
if kind == 'new'
|
|
36
|
-
variables = { '
|
|
36
|
+
variables = { 'new' => variables_importer.get_variables_names(role.name) }
|
|
37
37
|
elsif kind == 'obsolete'
|
|
38
|
-
variables = { '
|
|
38
|
+
variables = { 'obsolete' => role.ansible_variables.map(&:key) }
|
|
39
39
|
elsif kind == 'old'
|
|
40
40
|
variables = get_old_roles_variables(imported_variables, role)
|
|
41
41
|
end
|
|
@@ -51,24 +51,25 @@ module ForemanAnsible
|
|
|
51
51
|
match.to_s.empty? ? nil : match
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
-
def prepare_api_row(role, kind, variables
|
|
54
|
+
def prepare_api_row(role, kind, variables)
|
|
55
55
|
{
|
|
56
56
|
name: role.name,
|
|
57
57
|
id: role.id,
|
|
58
|
-
role_action:
|
|
58
|
+
role_action: role_action_name(kind),
|
|
59
59
|
variables: variables,
|
|
60
|
-
hosts_count:
|
|
61
|
-
hostgroup_count:
|
|
60
|
+
hosts_count: kind == 'obsolete' ? role.hosts.count : '',
|
|
61
|
+
hostgroup_count: kind == 'obsolete' ? role.hostgroups.count : '',
|
|
62
62
|
kind: kind
|
|
63
63
|
}
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
-
def prepare_ui_row(role, kind, variables
|
|
66
|
+
def prepare_ui_row(role, kind, variables)
|
|
67
67
|
{ cells: [
|
|
68
68
|
role.name,
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
role_action_name(kind),
|
|
70
|
+
variables,
|
|
71
|
+
kind == 'obsolete' ? role.hosts.count : '',
|
|
72
|
+
kind == 'obsolete' ? role.hostgroups.count : ''
|
|
72
73
|
],
|
|
73
74
|
role: role, kind: kind, id: role.name }
|
|
74
75
|
end
|
|
@@ -81,11 +82,10 @@ module ForemanAnsible
|
|
|
81
82
|
next if role_match_excluded_roles(role.name)
|
|
82
83
|
variables = get_roles_variables(imported_variables, variables_importer, kind, role)
|
|
83
84
|
next if variables.empty? && kind['old']
|
|
84
|
-
role_action = get_role_action(kind)
|
|
85
85
|
if is_ui
|
|
86
|
-
rows.append(prepare_ui_row(role, kind, variables
|
|
86
|
+
rows.append(prepare_ui_row(role, kind, variables))
|
|
87
87
|
else
|
|
88
|
-
rows.append(prepare_api_row(role, kind, variables
|
|
88
|
+
rows.append(prepare_api_row(role, kind, variables))
|
|
89
89
|
end
|
|
90
90
|
end
|
|
91
91
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require '
|
|
3
|
+
require 'resolv'
|
|
4
4
|
module ForemanAnsible
|
|
5
5
|
# Relations to make Host::Managed 'have' ansible roles
|
|
6
6
|
module HostManagedExtensions
|
|
@@ -16,7 +16,7 @@ module ForemanAnsible
|
|
|
16
16
|
:dependent => :destroy
|
|
17
17
|
scoped_search :relation => :ansible_roles, :on => :name,
|
|
18
18
|
:complete_value => true, :rename => :ansible_role,
|
|
19
|
-
:only_explicit => true
|
|
19
|
+
:only_explicit => true, ext_method: :search_by_role
|
|
20
20
|
|
|
21
21
|
before_provision :play_ansible_roles
|
|
22
22
|
audit_associations :ansible_roles
|
|
@@ -30,6 +30,14 @@ module ForemanAnsible
|
|
|
30
30
|
hostgroup.inherited_and_own_ansible_roles
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
+
def own_ansible_roles
|
|
34
|
+
ansible_roles.where.not(:id => inherited_ansible_roles.pluck(:id))
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def available_ansible_roles
|
|
38
|
+
AnsibleRole.where.not(:id => all_ansible_roles.pluck(:id))
|
|
39
|
+
end
|
|
40
|
+
|
|
33
41
|
# This one should be fixed, disabled for the moment as we're
|
|
34
42
|
# in a rush to get the release out
|
|
35
43
|
def play_ansible_roles
|
|
@@ -39,7 +47,7 @@ module ForemanAnsible
|
|
|
39
47
|
composer.triggering.mode = :future
|
|
40
48
|
composer.triggering.start_at = (
|
|
41
49
|
Time.zone.now +
|
|
42
|
-
Setting
|
|
50
|
+
Setting[:ansible_post_provision_timeout].to_i.seconds
|
|
43
51
|
)
|
|
44
52
|
composer.trigger!
|
|
45
53
|
logger.info("Task for Ansible roles on #{self} before_provision: "\
|
|
@@ -58,12 +66,23 @@ module ForemanAnsible
|
|
|
58
66
|
def import_host(*args)
|
|
59
67
|
host = super(*args)
|
|
60
68
|
hostname = args[0]
|
|
61
|
-
if
|
|
69
|
+
if (Resolv::IPv4::Regex.match?(hostname) || Resolv::IPv6::Regex.match?(hostname)) &&
|
|
62
70
|
(host_nic = Nic::Interface.find_by(:ip => hostname))
|
|
63
71
|
host = host_nic.host
|
|
64
72
|
end
|
|
65
73
|
host
|
|
66
74
|
end
|
|
75
|
+
|
|
76
|
+
def search_by_role(_key, operator, value)
|
|
77
|
+
conditions = sanitize_sql_for_conditions(["ansible_roles.name #{operator} ?", value_to_sql(operator, value)])
|
|
78
|
+
host_ids = ::Host::Managed.joins(:ansible_roles).where(conditions).distinct.pluck(:id)
|
|
79
|
+
hostgroup_ids = ::Hostgroup.unscoped.with_taxonomy_scope.joins(:ansible_roles).where(conditions).map(&:subtree_ids).flatten
|
|
80
|
+
|
|
81
|
+
conds = []
|
|
82
|
+
conds << "hosts.id IN(#{host_ids.join(',')})" if host_ids.present?
|
|
83
|
+
conds << "hosts.hostgroup_id IN(#{hostgroup_ids.uniq.join(',')})" if hostgroup_ids.present?
|
|
84
|
+
{ conditions: conds.join(' OR ').presence || '1 = 0' }
|
|
85
|
+
end
|
|
67
86
|
end
|
|
68
87
|
end
|
|
69
88
|
end
|
|
@@ -6,13 +6,14 @@ module ForemanAnsible
|
|
|
6
6
|
extend ActiveSupport::Concern
|
|
7
7
|
|
|
8
8
|
included do
|
|
9
|
-
has_many :hostgroup_ansible_roles, :foreign_key => :hostgroup_id
|
|
9
|
+
has_many :hostgroup_ansible_roles, -> { order('hostgroup_ansible_roles.position ASC') }, :foreign_key => :hostgroup_id
|
|
10
10
|
has_many :ansible_roles,
|
|
11
11
|
-> { order('hostgroup_ansible_roles.position ASC') },
|
|
12
12
|
:through => :hostgroup_ansible_roles,
|
|
13
13
|
:dependent => :destroy
|
|
14
14
|
accepts_nested_attributes_for :hostgroup_ansible_roles, :allow_destroy => true
|
|
15
15
|
audit_associations :ansible_roles
|
|
16
|
+
include_in_clone :ansible_roles
|
|
16
17
|
|
|
17
18
|
def inherited_ansible_roles
|
|
18
19
|
ancestors.reduce([]) do |roles, hostgroup|
|
|
@@ -32,12 +32,14 @@ if defined? ForemanRemoteExecution
|
|
|
32
32
|
template_invocation.template
|
|
33
33
|
),
|
|
34
34
|
:name => host.name,
|
|
35
|
-
:check_mode => host.host_param('ansible_roles_check_mode')
|
|
35
|
+
:check_mode => host.host_param('ansible_roles_check_mode'),
|
|
36
|
+
:cleanup_working_dirs => cleanup_working_dirs?(host)
|
|
36
37
|
)
|
|
37
38
|
end
|
|
38
39
|
|
|
39
40
|
def secrets(host)
|
|
40
41
|
{
|
|
42
|
+
:key_passphrase => Setting[:remote_execution_ssh_key_passphrase],
|
|
41
43
|
'per-host' => {
|
|
42
44
|
host.name => {
|
|
43
45
|
'ansible_password' => rex_ssh_password(host),
|
|
@@ -55,10 +57,6 @@ if defined? ForemanRemoteExecution
|
|
|
55
57
|
host_setting(host, 'remote_execution_effective_user_password')
|
|
56
58
|
end
|
|
57
59
|
|
|
58
|
-
def host_setting(host, setting)
|
|
59
|
-
host.params[setting.to_s] || Setting[setting]
|
|
60
|
-
end
|
|
61
|
-
|
|
62
60
|
def supports_effective_user?
|
|
63
61
|
true
|
|
64
62
|
end
|
|
@@ -90,7 +88,7 @@ if defined? ForemanRemoteExecution
|
|
|
90
88
|
:children => [
|
|
91
89
|
{
|
|
92
90
|
:name => :tags,
|
|
93
|
-
:type =>
|
|
91
|
+
:type => String,
|
|
94
92
|
:opts => { :required => false, :desc => N_('A comma separated list of tags to use for Ansible run') }
|
|
95
93
|
},
|
|
96
94
|
{
|
|
@@ -116,6 +114,10 @@ if defined? ForemanRemoteExecution
|
|
|
116
114
|
'Proxy::Ansible::TaskLauncher::Playbook::PlaybookRunnerAction'
|
|
117
115
|
end
|
|
118
116
|
|
|
117
|
+
def proxy_batch_size
|
|
118
|
+
Setting['foreman_ansible_proxy_batch_size']
|
|
119
|
+
end
|
|
120
|
+
|
|
119
121
|
private
|
|
120
122
|
|
|
121
123
|
def ansible_command?(template)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require '
|
|
3
|
+
require 'resolv'
|
|
4
4
|
module ForemanAnsible
|
|
5
5
|
# Ensures Ansible reports from hosts where the IP was used, are assigned
|
|
6
6
|
# to the right hostname in Foreman
|
|
@@ -10,7 +10,7 @@ module ForemanAnsible
|
|
|
10
10
|
def host
|
|
11
11
|
hostname = name.downcase
|
|
12
12
|
if AnsibleReportScanner.ansible_report?(raw) &&
|
|
13
|
-
|
|
13
|
+
(Resolv::IPv4::Regex.match?(hostname) || Resolv::IPv6::Regex.match?(hostname)) &&
|
|
14
14
|
Nic::Interface.find_by(:ip => hostname)
|
|
15
15
|
@host = Nic::Interface.find_by(:ip => hostname).host
|
|
16
16
|
end
|
|
@@ -18,10 +18,6 @@ module ForemanAnsible
|
|
|
18
18
|
partial_hostname_match(hostname)
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
def self.authorized_smart_proxy_features
|
|
22
|
-
super + ['Ansible']
|
|
23
|
-
end
|
|
24
|
-
|
|
25
21
|
def partial_hostname_match(hostname)
|
|
26
22
|
return @host unless @host.new_record?
|
|
27
23
|
hosts = Host.where(Host.arel_table[:name].matches("#{hostname}.%"))
|
|
@@ -103,7 +103,7 @@ module ForemanAnsible
|
|
|
103
103
|
'ansible_port' => host_setting(host, 'remote_execution_ssh_port'),
|
|
104
104
|
'ansible_host' => AnsibleProvider.find_ip_or_hostname(host)
|
|
105
105
|
}
|
|
106
|
-
if @template_invocation.effective_user.present?
|
|
106
|
+
if @template_invocation.effective_user.present? && @template_invocation.effective_user != params['ansible_user']
|
|
107
107
|
params['ansible_become_user'] = @template_invocation.effective_user
|
|
108
108
|
params['ansible_become'] = true
|
|
109
109
|
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module ForemanAnsible
|
|
2
|
+
# Service which resolves override values for hosts
|
|
3
|
+
class OverrideResolver
|
|
4
|
+
attr_reader :overrides, :ansible_variables
|
|
5
|
+
|
|
6
|
+
def initialize(host, variable_ids = [])
|
|
7
|
+
raise(Foreman::Exception.new('OverrideResolver needs a host to resolve overrides')) unless host
|
|
8
|
+
@ansible_variables = if variable_ids.empty?
|
|
9
|
+
AnsibleVariable.where(:ansible_role_id => host.all_ansible_roles, :override => true)
|
|
10
|
+
else
|
|
11
|
+
AnsibleVariable.where(:id => variable_ids, :override => true)
|
|
12
|
+
end
|
|
13
|
+
@overrides = @ansible_variables.values_hash(host).raw
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def resolve(ansible_variable)
|
|
17
|
+
override = @overrides[ansible_variable.id]
|
|
18
|
+
return unless override
|
|
19
|
+
override[ansible_variable.key]
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -10,7 +10,7 @@ attributes :id, :variable, :ansible_role, :ansible_role_id, :description, :overr
|
|
|
10
10
|
node do |ansible_variable|
|
|
11
11
|
{
|
|
12
12
|
:override_values => partial(
|
|
13
|
-
'api/v2/
|
|
13
|
+
'api/v2/ansible_override_values/index',
|
|
14
14
|
:object => ansible_variable.lookup_values
|
|
15
15
|
)
|
|
16
16
|
}
|
|
@@ -5,11 +5,14 @@
|
|
|
5
5
|
display_link_if_authorized(_('Run all Ansible roles'), hash_for_play_roles_hostgroup_path(id: hostgroup), :'data-no-turbolink' => true, title: _('Run all Ansible roles on hosts belonging to this host group'))
|
|
6
6
|
end
|
|
7
7
|
|
|
8
|
+
assign_jobs = link_to(_("Configure Ansible Job"), "/ansible/hostgroups/#{hostgroup.id}", { class: 'la' })
|
|
9
|
+
|
|
8
10
|
actions = [
|
|
9
11
|
display_link_if_authorized(_('Nest'), hash_for_nest_hostgroup_path(:id => hostgroup)),
|
|
10
12
|
display_link_if_authorized(_('Clone'), hash_for_clone_hostgroup_path(:id => hostgroup))
|
|
11
13
|
]
|
|
12
14
|
actions.push play_roles if User.current.can?(:create_job_invocations)
|
|
15
|
+
actions.push assign_jobs if User.current.can?(:view_job_invocations) && User.current.can?(:view_recurring_logics)
|
|
13
16
|
actions.push display_delete_if_authorized(hash_for_hostgroup_path(:id => hostgroup).merge(:auth_object => hostgroup, :authorizer => authorizer), :data => { :confirm => warning_message(hostgroup) })
|
|
14
17
|
|
|
15
18
|
action_buttons(*actions)
|
|
@@ -5,13 +5,17 @@ template_inputs:
|
|
|
5
5
|
- name: Activation Key
|
|
6
6
|
required: true
|
|
7
7
|
input_type: user
|
|
8
|
+
description: Set the activation key to assign the desired RHEL subscription and
|
|
9
|
+
life cycle environment to the converted machine at the registration step.
|
|
8
10
|
advanced: false
|
|
9
|
-
value_type:
|
|
11
|
+
value_type: resource
|
|
10
12
|
resource_type: Katello::ActivationKey
|
|
11
13
|
hidden_value: false
|
|
12
14
|
- name: Restart
|
|
13
15
|
required: true
|
|
14
16
|
input_type: user
|
|
17
|
+
description: Restart the system when it is successfully converted to RHEL to boot
|
|
18
|
+
the new RHEL kernel.
|
|
15
19
|
options: "yes\r\nno"
|
|
16
20
|
advanced: false
|
|
17
21
|
value_type: plain
|
|
@@ -34,7 +38,7 @@ kind: job_template
|
|
|
34
38
|
url: <%= subscription_manager_configuration_url(@host) %>
|
|
35
39
|
dest: /usr/share/convert2rhel/subscription-manager/katello-ca-consumer-latest.noarch.rpm
|
|
36
40
|
- name: Start convert2rhel
|
|
37
|
-
command: convert2rhel -y --activationkey "<%=
|
|
41
|
+
command: convert2rhel -y --activationkey "<%= input_resource('Activation Key').name %>" --org "<%= @host.organization.label %>" --keep-rhsm
|
|
38
42
|
<%- if input('Restart') == "yes" -%>
|
|
39
43
|
- name: Reboot the machine
|
|
40
44
|
reboot:
|