hammer_cli_foreman_ansible 0.3.4 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 22b04f4732021b83a5f201c450ae645183a249b1fac74f9573eebc5b893e4761
4
- data.tar.gz: 1e9a7ce94688a284ebd784178cc479ce19e83e1a5ba5c2e28d259ca1a5508565
3
+ metadata.gz: e2378fa0dc9b16ad52e6fb9c3d368c23b2d8db6d4ba64bfc31e273b1ba1b2e21
4
+ data.tar.gz: 3d702aa4392493735abd50d5acf2f382e9f5c42809d2d7b13558df951fb5e87c
5
5
  SHA512:
6
- metadata.gz: 8444e5efcd1d36fef6925ae3fb2a6320c74da8d8a9e05e18efc257214ec2d7607bb8267f8d4451177f875fb69dc38da57c6ef844dfb84d57c3a506d98a410039
7
- data.tar.gz: c3622e78574949e8ea728f18cbe6fc8368a2f6d4052c3015da1151d4ce0a7ad83d4c9fb872cca12d257dea6d3763377f49426c9c0018b19571b47fef111890ec
6
+ metadata.gz: '09b412c43b4a0050ee41d2e7e2657c1928c81fe1d84ead4323c70e254e92e31ac980c904b2c0d5f4e06f7970ab6269b60fb3d4ce39329607ee3328f0d25b6f56'
7
+ data.tar.gz: d8e97a5f33a6fa060f8f3b8c29886c8827eb5bca2170290dbce026c80bfbef2ae53878c96b0269a9e3863df7985189ecefa8b98419c8bfc81bab2323fcd10ffb
@@ -16,6 +16,12 @@ module HammerCLIForemanAnsible
16
16
  'hammer_cli_foreman_ansible/ansible_variables'
17
17
  )
18
18
 
19
+ lazy_subcommand(
20
+ 'inventory',
21
+ _('Ansible Inventory'),
22
+ 'HammerCLIForemanAnsible::AnsibleInventoryCommand',
23
+ 'hammer_cli_foreman_ansible/ansible_inventory'
24
+ )
19
25
  autoload_subcommands
20
26
  end
21
27
  end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HammerCLIForemanAnsible
4
+ class AnsibleInventoryCommand < HammerCLIForeman::Command
5
+ resource :ansible_inventories
6
+
7
+ class HostsCommand < HammerCLIForeman::Command
8
+ action :hosts
9
+ command_name 'hosts'
10
+ option '--as-json', :flag, _('Full response as json')
11
+
12
+ def print_data(data)
13
+ return super unless option_as_json?
14
+
15
+ puts JSON.pretty_generate(data)
16
+ end
17
+ build_options
18
+
19
+ extend_with(HammerCLIForemanAnsible::CommandExtensions::Inventory.new)
20
+ end
21
+
22
+ class HostgroupsCommand < HammerCLIForeman::Command
23
+ action :hostgroups
24
+ command_name 'hostgroups'
25
+ option '--as-json', :flag, _('Full response as json')
26
+
27
+ def print_data(data)
28
+ return super unless option_as_json?
29
+
30
+ puts JSON.pretty_generate(data)
31
+ end
32
+ build_options
33
+
34
+ extend_with(HammerCLIForemanAnsible::CommandExtensions::Inventory.new)
35
+ end
36
+
37
+ class ScheduleCommand < HammerCLIForeman::Command
38
+ action :schedule
39
+ command_name 'schedule'
40
+
41
+ output do
42
+ field :job_id, _('Job Id')
43
+ field :data_url, _('Data URL')
44
+ end
45
+
46
+ build_options
47
+ end
48
+
49
+ autoload_subcommands
50
+ end
51
+ end
52
+
@@ -0,0 +1,85 @@
1
+ module HammerCLIForemanAnsible
2
+ module AssociatedAnsibleRole
3
+ # This method fetches all associated resource (ansible roles) ids
4
+ # to send them back via :update endpoint of the main resource (host/hostgroup)
5
+ # We use this array of ids to add or remove direct associations
6
+ # This method is used to 'reset' associated ids via HammerCLIForeman::[Add|Remove]AssociatedCommand
7
+ def get_current_ids
8
+ roles = HammerCLIForeman.record_to_common_format(resource.call(association_name(true), { id: get_identifier }))
9
+ return ids_to_keep_for_removal(roles) if self.class.command_names.include?('remove')
10
+
11
+ ids_to_keep_for_addition(roles)
12
+ end
13
+
14
+ # Since there are no option_sources available to deal with such cases (AssociatedCommand)
15
+ # Make sure we get id of the provided role before we try to get already associated ones
16
+ def get_new_ids
17
+ associated_identifiers = get_associated_identifiers
18
+ @associated_identifier = get_associated_identifier
19
+
20
+ ids = get_current_ids.map(&:to_s)
21
+
22
+ required_ids = associated_identifiers.nil? ? [] : associated_identifiers.map(&:to_s)
23
+ required_ids << @associated_identifier.to_s unless @associated_identifier.nil?
24
+
25
+ ids = if self.class.command_names.include?('remove')
26
+ ids.delete_if { |id| required_ids.include? id }
27
+ else
28
+ ids + required_ids
29
+ end
30
+ ids.uniq
31
+ end
32
+
33
+ private
34
+
35
+ # Treat inherited as we do in UI:
36
+ # - Don't allow to directly associate them (the role is not available to select)
37
+ # - If the same role was assigned AND inherited then treat it as it was just assigned (keep it)
38
+ # - If the role is indirectly associated only then don't associate it directly unless --force provided
39
+ def ids_to_keep_for_addition(roles)
40
+ roles.map do |role|
41
+ # Keep directly associated roles
42
+ next role['id'] if role['directly_assigned']
43
+
44
+ # Host groups can have not inherited and not directly assigned roles in the response.
45
+ # This means those roles are from hosts, skip them.
46
+ # Hosts cannot have such case.
47
+
48
+ # Pre-check to force stop the command if we're trying to add an already inherited role
49
+ # (in case we don't have it directly associated as well)
50
+ if @associated_identifier == role['id'] && role['inherited']
51
+ next role['id'] if option_force?
52
+
53
+ msg = _(
54
+ 'Ansible role %{name} is already inherited from a host group. Please use %{option} for direct association.'
55
+ ) % { name: role['name'], option: '--force' }
56
+ raise ArgumentError, msg
57
+ end
58
+
59
+ # We skip not directly assigned and inherited
60
+ # Also skip not inherited for host groups
61
+ nil
62
+ end.compact
63
+ end
64
+
65
+ # Treat inherited as we do in UI:
66
+ # - Don't allow to remove them (the role is not available to select)
67
+ # - If the same role was assigned AND inherited then treat it as it was just assigned (keep or remove it)
68
+ # - If the role was inherited only then don't remove it
69
+ def ids_to_keep_for_removal(roles)
70
+ roles.map do |role|
71
+ # Keep or remove later directly associated roles
72
+ next role['id'] if role['directly_assigned']
73
+
74
+ # Pre-check to force stop the command if we're trying to remove not directly assigned role
75
+ if role['id'] == @associated_identifier
76
+ raise ArgumentError, _('Ansible role %s is not assigned directly and cannot be removed.') % role['name']
77
+ end
78
+
79
+ # We skip not directly assigned and inherited
80
+ # Also skip not inherited for host groups
81
+ nil
82
+ end.compact
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HammerCLIForemanAnsible
4
+ module CommandExtensions
5
+ class Inventory < HammerCLI::CommandExtensions
6
+ output do |definition|
7
+ definition.append do
8
+ from 'foreman' do
9
+ field :hostname, _('Name')
10
+ field :fqdn, _('FQDN')
11
+ field :hostgroup, _('Host Group')
12
+ field :location, _('Location')
13
+ field :organization, _('Organization')
14
+ field :domainname, _('Domain')
15
+ field :foreman_domain_description, _('Foreman domain description')
16
+ field :owner_name, _('Owner name')
17
+ field :owner_email, _('Owner email')
18
+ field :ssh_authorized_keys, _('SSH authorized keys')
19
+ field :root_pw, _('Root password')
20
+ field :foreman_config_groups, _('Foreman config groups')
21
+ field :puppetmaster, _('Puppet master')
22
+ field :foreman_env, _('Puppet environment')
23
+
24
+ collection :foreman_subnets, _('Subnets') do
25
+ field :name, _('Name')
26
+ field :network, _('Network')
27
+ field :mask, _('Mask')
28
+ field :gateway, _('Gateway')
29
+ field :dns_primary, _('Primary DNS')
30
+ field :dns_secondary, _('Secondary DNS')
31
+ field :from, _('From')
32
+ field :to, _('To')
33
+ field :boot_mode, _('Boot mode')
34
+ field :ipam, _('IPAM')
35
+ field :vlanid, _('VLAN ID')
36
+ field :mtu, _('MTU')
37
+ field :nic_delay, _('NIC delay')
38
+ field :network_type, _('Network type')
39
+ field :description, _('Description')
40
+ end
41
+
42
+ collection :foreman_interfaces, _('Network interfaces') do
43
+ field :name, _('Interface Name')
44
+ field :identifier, _('Identifier')
45
+ field :attrs, _('Attributes'),Fields::Field, hide_blank: true
46
+ field :mac, _('MAC address')
47
+ field :ip, _('IPv4 address'), Fields::Field, hide_blank: true
48
+ field :ip6, _('IPv6 address'), Fields::Field, hide_blank: true
49
+ field :virtual, _('Virtual'), Fields::Boolean
50
+ field :link, _('Link'), Fields::Boolean
51
+ field :managed, _('Managed'), Fields::Boolean
52
+ field :primary, _('Primary'), Fields::Boolean
53
+ field :provision, _('Provision'), Fields::Boolean
54
+ field :subnet6, _('IPv6 subnet')
55
+ field :tag, _('Tag')
56
+ field :attached_to, _('Attached to')
57
+ field :type, _('Type')
58
+ field :attached_devices, _('Attached devices')
59
+ from 'subnet' do
60
+ label _('Subnet'), hide_blank: true do
61
+ field :name, _('Name')
62
+ field :network, _('Network')
63
+ field :mask, _('Mask')
64
+ field :gateway, _('Gateway')
65
+ field :dns_primary, _('Primary DNS')
66
+ field :dns_secondary, _('Secondary DNS')
67
+ field :from, _('From')
68
+ field :to, _('To')
69
+ field :boot_mode, _('Boot mode')
70
+ field :ipam, _('IPAM')
71
+ field :vlanid, _('VLAN ID')
72
+ field :mtu, _('MTU')
73
+ field :nic_delay, _('NIC delay')
74
+ field :network_type, _('Network type')
75
+ field :description, _('Description')
76
+ end
77
+ end
78
+ end
79
+
80
+ collection :foreman_users, _('Foreman Users'), numbered: false do
81
+ field :firstname, _('First name')
82
+ field :lastname, _('Last name')
83
+ field :mail, _('Email')
84
+ field :description, _('Description')
85
+ field :fullname, _('Full name')
86
+ field :ssh_authorized_keys, _('SSH authorized keys')
87
+ end
88
+ end
89
+
90
+ collection :foreman_ansible_roles, _('Foreman Ansible Roles'), numbered: false do
91
+ field :name, _('Role')
92
+ end
93
+
94
+ field :ansible_roles_check_mode, _('Ansible role check mode'), Fields::Boolean
95
+ field :host_packages, _('Host packages')
96
+ field :host_registration_insights, _('Host registration insights'), Fields::Boolean
97
+ field :host_registration_remote_execution, _('Host registration remote execution'), Fields::Boolean
98
+ field :remote_execution_ssh_keys, _('Remote execution ssh keys')
99
+ field :remote_execution_ssh_user, _('Remote execution ssh user')
100
+ field :remote_execution_effective_user_method, _('Remote execution effective user method')
101
+ field :remote_execution_connect_by_ip, _('Remote execution connect by IP'), Fields::Boolean
102
+ end
103
+ end
104
+
105
+ before_print do |data, cmd_obj|
106
+ unless cmd_obj.option_as_json?
107
+ new_data = data['all']['hosts'].each_with_object([]) do |hostname, arr|
108
+ data['_meta']['hostvars'][hostname]['foreman']['foreman_users'] = data['_meta']['hostvars'][hostname]['foreman']['foreman_users']&.map { |u| u[1] }
109
+ data['_meta']['hostvars'][hostname]['foreman_ansible_roles'] = data['_meta']['hostvars'][hostname]['foreman_ansible_roles']&.map { |r| { 'name' => r } }
110
+ arr << {
111
+ 'hostname' => hostname
112
+ }.merge(data['_meta']['hostvars'][hostname])
113
+ end
114
+ data.clear
115
+ data['results'] = new_data
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HammerCLIForemanAnsible
4
+ module CommandExtensions
5
+ class JobTemplate < HammerCLI::CommandExtensions
6
+ before_print do |data|
7
+ unless data['provider_type'] == 'Ansible'
8
+ data.delete('ansible_callback_enabled')
9
+ end
10
+ end
11
+
12
+ output do |definition|
13
+ definition.insert(:before, :description) do
14
+ field :ansible_callback_enabled, _('Ansible Callback Enabled'), Fields::Boolean
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1 +1,3 @@
1
1
  require 'hammer_cli_foreman_ansible/command_extensions/resolver'
2
+ require 'hammer_cli_foreman_ansible/command_extensions/inventory'
3
+ require 'hammer_cli_foreman_ansible/command_extensions/job_template'
@@ -11,7 +11,10 @@ module HammerCLIForemanAnsible
11
11
  class ListCommand < HammerCLIForeman::ListCommand
12
12
  action :ansible_roles
13
13
 
14
- output HammerCLIForemanAnsible::AnsibleRolesCommand::ListCommand.output_definition
14
+ output(HammerCLIForemanAnsible::AnsibleRolesCommand::ListCommand.output_definition) do
15
+ field :inherited, _('Inherited'), Fields::Boolean
16
+ field :directly_assigned, _('Directly assigned'), Fields::Boolean
17
+ end
15
18
 
16
19
  build_options
17
20
  end
@@ -35,6 +38,45 @@ module HammerCLIForemanAnsible
35
38
 
36
39
  build_options
37
40
  end
41
+
42
+ class AddAnsibleRoleCommand < HammerCLIForeman::AddAssociatedCommand
43
+ prepend HammerCLIForemanAnsible::AssociatedAnsibleRole
44
+
45
+ command_name 'add'
46
+ associated_resource :ansible_roles
47
+ desc _('Associate an Ansible role')
48
+
49
+ option '--force', :flag, _('Associate the Ansible role even if it already is associated indirectly')
50
+
51
+ success_message _('Ansible role has been associated.')
52
+ failure_message _('Could not associate the Ansible role')
53
+
54
+ validate_options do
55
+ any(:option_name, :option_id).required
56
+ any(:option_ansible_role_name, :option_ansible_role_id).required
57
+ end
58
+
59
+ build_options
60
+ end
61
+
62
+ class RemoveAnsibleRoleCommand < HammerCLIForeman::RemoveAssociatedCommand
63
+ prepend HammerCLIForemanAnsible::AssociatedAnsibleRole
64
+
65
+ command_name 'remove'
66
+ associated_resource :ansible_roles
67
+ desc _('Disassociate an Ansible role')
68
+
69
+ success_message _('Ansible role has been disassociated.')
70
+ failure_message _('Could not disassociate the Ansible role')
71
+
72
+ validate_options do
73
+ any(:option_name, :option_id).required
74
+ any(:option_ansible_role_name, :option_ansible_role_id).required
75
+ end
76
+
77
+ build_options
78
+ end
79
+
38
80
  autoload_subcommands
39
81
  end
40
82
  end
@@ -11,7 +11,10 @@ module HammerCLIForemanAnsible
11
11
  class ListCommand < HammerCLIForeman::ListCommand
12
12
  action :ansible_roles
13
13
 
14
- output HammerCLIForemanAnsible::AnsibleRolesCommand::ListCommand.output_definition
14
+ output(HammerCLIForemanAnsible::AnsibleRolesCommand::ListCommand.output_definition) do
15
+ field :inherited, _('Inherited'), Fields::Boolean
16
+ field :directly_assigned, _('Directly assigned'), Fields::Boolean
17
+ end
15
18
 
16
19
  build_options
17
20
  end
@@ -36,6 +39,44 @@ module HammerCLIForemanAnsible
36
39
  build_options
37
40
  end
38
41
 
42
+ class AddAnsibleRoleCommand < HammerCLIForeman::AddAssociatedCommand
43
+ prepend HammerCLIForemanAnsible::AssociatedAnsibleRole
44
+
45
+ command_name 'add'
46
+ associated_resource :ansible_roles
47
+ desc _('Associate an Ansible role')
48
+
49
+ option '--force', :flag, _('Associate the Ansible role even if it already is associated indirectly')
50
+
51
+ success_message _('Ansible role has been associated.')
52
+ failure_message _('Could not associate the Ansible role')
53
+
54
+ validate_options do
55
+ any(:option_name, :option_title, :option_id).required
56
+ any(:option_ansible_role_name, :option_ansible_role_id).required
57
+ end
58
+
59
+ build_options
60
+ end
61
+
62
+ class RemoveAnsibleRoleCommand < HammerCLIForeman::RemoveAssociatedCommand
63
+ prepend HammerCLIForemanAnsible::AssociatedAnsibleRole
64
+
65
+ command_name 'remove'
66
+ associated_resource :ansible_roles
67
+ desc _('Disassociate an Ansible role')
68
+
69
+ success_message _('Ansible role has been disassociated.')
70
+ failure_message _('Could not disassociate the Ansible role')
71
+
72
+ validate_options do
73
+ any(:option_name, :option_title, :option_id).required
74
+ any(:option_ansible_role_name, :option_ansible_role_id).required
75
+ end
76
+
77
+ build_options
78
+ end
79
+
39
80
  autoload_subcommands
40
81
  end
41
82
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module HammerCLIForemanAnsible
4
4
  def self.version
5
- @version ||= Gem::Version.new '0.3.4'
5
+ @version ||= Gem::Version.new '0.5.0'
6
6
  end
7
7
  end
@@ -3,16 +3,20 @@ module HammerCLIForemanAnsible
3
3
  require 'hammer_cli_foreman'
4
4
  require 'hammer_cli_foreman/host'
5
5
  require 'hammer_cli_foreman/hostgroup'
6
+ require 'hammer_cli_foreman_remote_execution'
6
7
 
7
8
  require 'hammer_cli_foreman_ansible/version'
8
9
  require 'hammer_cli_foreman_ansible/i18n'
9
10
  require 'hammer_cli_foreman_ansible/ansible'
10
11
  require 'hammer_cli_foreman_ansible/ansible_roles'
12
+ require 'hammer_cli_foreman_ansible/associated_ansible_role'
11
13
  require 'hammer_cli_foreman_ansible/host'
12
14
  require 'hammer_cli_foreman_ansible/hostgroup'
13
15
 
14
16
  require 'hammer_cli_foreman_ansible/command_extensions'
15
17
 
18
+ HammerCLIForemanRemoteExecution::JobTemplate::InfoCommand.extend_with(HammerCLIForemanAnsible::CommandExtensions::JobTemplate.new)
19
+
16
20
  HammerCLI::MainCommand.lazy_subcommand(
17
21
  'ansible',
18
22
  'Manage foreman ansible',