hammer_cli_foreman_ansible 0.3.2 → 0.4.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
- SHA1:
3
- metadata.gz: 4be510cfce6a703825aef89bb9790b9d1d0cd7e0
4
- data.tar.gz: cf4f2b25be3c5badcde36856278777f19eff41f1
2
+ SHA256:
3
+ metadata.gz: 12f80a5bb288d8683aad9b3629edffbbd32bfb4afdf7aa597e4b370e2c19da58
4
+ data.tar.gz: 03d9f616b2d17580d15e93cae6fb79e0c6b599091fa4f0ed9cb7d6d2db986cdf
5
5
  SHA512:
6
- metadata.gz: cb77aad37001df22b6a3edf555ba99166337013a5b7db0c9c310ca1dcbc27687752765ec36b7173bea4523ede553abd37c4a561cde70e2193fed8fb648c4d91d
7
- data.tar.gz: 5030327b8b640ab59f3f5c847ad4ff8eeffd853c53b869fab9ee3ff8c3a433db2cc8b55fb6c3fc15fa76262c21803c4a03924b5ee115025aba612399fa2d825e
6
+ metadata.gz: 12f88c7777fae85e77ae1288aafb09e08d569989b7a19bedbc939cbaa0d374161b47e23de3f3a4ec35ae78567982d0dc832f4974a14223d0aed05e76092ff7f1
7
+ data.tar.gz: 4bf5229134f1ce01c9ab517d5a9adb9281a5b9be0cced399fa78bbe55134e571525e51e9aed1c7802ef464a36162f7965eb3683faa294b89f5f99cf73be19c7f
@@ -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
+
@@ -25,6 +25,15 @@ module HammerCLIForemanAnsible
25
25
  build_options
26
26
  end
27
27
 
28
+ class SyncCommand < HammerCLIForeman::Command
29
+ action :sync
30
+ command_name 'sync'
31
+
32
+ success_message _('A task to Sync Ansible Roles was created.')
33
+ failure_message _('Could not sync roles')
34
+ build_options
35
+ end
36
+
28
37
  class ImportCommand < HammerCLIForeman::Command
29
38
  action :import
30
39
  command_name 'import'
@@ -87,7 +96,13 @@ module HammerCLIForemanAnsible
87
96
 
88
97
  output do
89
98
  collection :ansible_roles, _('Ansible roles available to be imported') do
90
- field :name, nil
99
+ field :name, _("Role Name")
100
+ field :role_action, _("Action")
101
+ field :variables, _("Variables")
102
+ field :hosts_count, ("Hosts count")
103
+ field :hostgroup_count, ("Hostgroup count")
104
+
105
+
91
106
  end
92
107
  end
93
108
 
@@ -5,6 +5,7 @@ module HammerCLIForemanAnsible
5
5
  resource :ansible_variables
6
6
 
7
7
  class ListCommand < HammerCLIForeman::ListCommand
8
+
8
9
  output do
9
10
  field :id, _('Id')
10
11
 
@@ -15,7 +16,6 @@ module HammerCLIForemanAnsible
15
16
  field :ansible_role, _('Role')
16
17
  field :ansible_role_id, _('Role Id'), Fields::Id
17
18
  end
18
-
19
19
  build_options
20
20
  end
21
21
 
@@ -64,6 +64,16 @@ module HammerCLIForemanAnsible
64
64
  success_message _("Ansible variable [%{variable}] updated.")
65
65
  failure_message _("Could not update the ansible variable")
66
66
 
67
+ option "--override-value-order", "OVERRIDE_VALUE_ORDER", _("The order in which values are resolved"),
68
+ :format => HammerCLI::Options::Normalizers::List.new
69
+
70
+ def request_params
71
+ params = super
72
+ override_order = params['ansible_variable']['override_value_order']
73
+ params['ansible_variable']['override_value_order'] = override_order.join("\n") if override_order.is_a?(Array)
74
+ params
75
+ end
76
+
67
77
  build_options
68
78
  end
69
79
 
@@ -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,15 @@
1
+ module HammerCLIForemanAnsible
2
+ module ResolverExtension
3
+ def create_ansible_roles_search_options(options, mode = nil)
4
+ if self.class.to_s == 'HammerCLIKatello::IdResolver'
5
+ create_search_options_without_katello_api(options, api.resource(:ansible_roles), mode)
6
+ else
7
+ create_search_options(options, api.resource(:ansible_roles), mode)
8
+ end
9
+ end
10
+ end
11
+
12
+ ::HammerCLIForeman::IdResolver.instance_eval do
13
+ include ResolverExtension
14
+ end
15
+ end
@@ -0,0 +1,2 @@
1
+ require 'hammer_cli_foreman_ansible/command_extensions/resolver'
2
+ require 'hammer_cli_foreman_ansible/command_extensions/inventory'
@@ -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.2'
5
+ @version ||= Gem::Version.new '0.4.0'
6
6
  end
7
7
  end
@@ -8,9 +8,12 @@ module HammerCLIForemanAnsible
8
8
  require 'hammer_cli_foreman_ansible/i18n'
9
9
  require 'hammer_cli_foreman_ansible/ansible'
10
10
  require 'hammer_cli_foreman_ansible/ansible_roles'
11
+ require 'hammer_cli_foreman_ansible/associated_ansible_role'
11
12
  require 'hammer_cli_foreman_ansible/host'
12
13
  require 'hammer_cli_foreman_ansible/hostgroup'
13
14
 
15
+ require 'hammer_cli_foreman_ansible/command_extensions'
16
+
14
17
  HammerCLI::MainCommand.lazy_subcommand(
15
18
  'ansible',
16
19
  'Manage foreman ansible',