foreman_discovery 12.0.2 → 13.0.1

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.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/app/mailers/discovered_mailer.rb +12 -1
  3. data/app/models/host/discovered.rb +20 -7
  4. data/app/models/setting/discovered.rb +2 -0
  5. data/app/services/foreman_discovery/fact_parser.rb +8 -2
  6. data/app/services/foreman_discovery/lldp_neighbors.rb +104 -0
  7. data/app/views/discovery_rules/index.html.erb +1 -1
  8. data/extra/discovery/pxeless-vlan.json +217 -0
  9. data/lib/foreman_discovery/engine.rb +1 -1
  10. data/lib/foreman_discovery/version.rb +1 -1
  11. data/locale/ca/LC_MESSAGES/foreman_discovery.mo +0 -0
  12. data/locale/ca/foreman_discovery.edit.po +143 -58
  13. data/locale/ca/foreman_discovery.po +4 -4
  14. data/locale/de/LC_MESSAGES/foreman_discovery.mo +0 -0
  15. data/locale/de/foreman_discovery.edit.po +145 -59
  16. data/locale/de/foreman_discovery.po +7 -7
  17. data/locale/en/LC_MESSAGES/foreman_discovery.mo +0 -0
  18. data/locale/en/foreman_discovery.edit.po +90 -58
  19. data/locale/en/foreman_discovery.po +28 -4
  20. data/locale/en_GB/LC_MESSAGES/foreman_discovery.mo +0 -0
  21. data/locale/en_GB/foreman_discovery.edit.po +151 -66
  22. data/locale/en_GB/foreman_discovery.po +12 -12
  23. data/locale/es/LC_MESSAGES/foreman_discovery.mo +0 -0
  24. data/locale/es/foreman_discovery.edit.po +155 -70
  25. data/locale/es/foreman_discovery.po +16 -16
  26. data/locale/foreman_discovery.pot +93 -59
  27. data/locale/fr/LC_MESSAGES/foreman_discovery.mo +0 -0
  28. data/locale/fr/foreman_discovery.edit.po +287 -200
  29. data/locale/fr/foreman_discovery.po +149 -148
  30. data/locale/gl/LC_MESSAGES/foreman_discovery.mo +0 -0
  31. data/locale/gl/foreman_discovery.edit.po +144 -59
  32. data/locale/gl/foreman_discovery.po +5 -5
  33. data/locale/it/LC_MESSAGES/foreman_discovery.mo +0 -0
  34. data/locale/it/foreman_discovery.edit.po +144 -59
  35. data/locale/it/foreman_discovery.po +5 -5
  36. data/locale/ja/LC_MESSAGES/foreman_discovery.mo +0 -0
  37. data/locale/ja/foreman_discovery.edit.po +153 -68
  38. data/locale/ja/foreman_discovery.po +16 -14
  39. data/locale/ko/LC_MESSAGES/foreman_discovery.mo +0 -0
  40. data/locale/ko/foreman_discovery.edit.po +143 -59
  41. data/locale/ko/foreman_discovery.po +5 -5
  42. data/locale/pt_BR/LC_MESSAGES/foreman_discovery.mo +0 -0
  43. data/locale/pt_BR/foreman_discovery.edit.po +155 -70
  44. data/locale/pt_BR/foreman_discovery.po +16 -16
  45. data/locale/ru/LC_MESSAGES/foreman_discovery.mo +0 -0
  46. data/locale/ru/foreman_discovery.edit.po +146 -63
  47. data/locale/ru/foreman_discovery.po +6 -6
  48. data/locale/sv_SE/LC_MESSAGES/foreman_discovery.mo +0 -0
  49. data/locale/sv_SE/foreman_discovery.edit.po +144 -59
  50. data/locale/sv_SE/foreman_discovery.po +5 -5
  51. data/locale/zh_CN/LC_MESSAGES/foreman_discovery.mo +0 -0
  52. data/locale/zh_CN/foreman_discovery.edit.po +150 -69
  53. data/locale/zh_CN/foreman_discovery.po +13 -15
  54. data/locale/zh_TW/LC_MESSAGES/foreman_discovery.mo +0 -0
  55. data/locale/zh_TW/foreman_discovery.edit.po +227 -144
  56. data/locale/zh_TW/foreman_discovery.po +88 -88
  57. data/test/functional/api/v2/discovery_rules_controller_test.rb +8 -0
  58. data/test/functional/api/v2/settings_controller_test.rb +2 -0
  59. data/test/test_helper_discovery.rb +2 -0
  60. data/test/unit/discovered_mailer_test.rb +14 -0
  61. data/test/unit/discovery_rule_test.rb +3 -0
  62. data/test/unit/facts_with_lldp.json +107 -0
  63. data/test/unit/facts_with_lldp_bond_candidate.json +107 -0
  64. data/test/unit/host_discovered_test.rb +72 -1
  65. data/test/unit/lldp_neighbors_test.rb +56 -0
  66. metadata +11 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c74650551a3323dcaa112a06e384b8bd5038df5622b71e327585cfa134efeb86
4
- data.tar.gz: 3e5dacb7e4c536048b38156ec69b265d79724424ab0917d239ec9144a52802f5
3
+ metadata.gz: 9ffdab95d6a69414a0b99ecdb838f4c9d4c2ee9f9eba3d71ba2a5bb3fe3ef3d0
4
+ data.tar.gz: 5e721d701c1d35f93dcec4f096b41cfcb08ea605bd46aa37a538349c61c2985d
5
5
  SHA512:
6
- metadata.gz: 2d6770e0543989dfa2270ece14eb165d45f2a6ccf82795247c372fc14dc81bff5efe87b3abf4964ce366fe1032b96d95e56777b6986fe61f1ce86851d734ce22
7
- data.tar.gz: 0f7262e88dbe6e92ebd3aff9bb888ede73744d250d7b308b99b3a39d6a992a9652ca422be8032e0a6c6090c2adcf6f5dd7ef62763a5e0fcb796f71e25d8aed36
6
+ metadata.gz: bac34ddb73174715645508c038e8d1951840374b8b32b0c8073f424522c0ff322645cc5dde847914cc2861f9363f8ad64aa943c9a48f04b947c37c633c48afb3
7
+ data.tar.gz: 37e531b52508c10f32617eae2af3beb893c9eee65698dbad324af1bb77212ca4659ab1a71b35f77b57ddaca3825f10fde2f452b6bf1e87fd6b0628616d4e00fb
@@ -1,7 +1,18 @@
1
1
  class DiscoveredMailer < ::ApplicationMailer
2
2
  helper :discovered_hosts
3
3
  def discovered_summary(options = {})
4
- raise ::Foreman::Exception.new(N_("Must specify a user with email enabled")) unless (user = User.find(options[:user])) && user.mail_enabled?
4
+ user = if options[:user].kind_of? User
5
+ options[:user]
6
+ elsif options[:user].kind_of? Integer
7
+ User.find(options[:user])
8
+ else
9
+ raise ::Foreman::Exception.new(N_('Invalid user type of %s was provided'), options[:user].class.to_s)
10
+ end
11
+
12
+ unless user.mail_enabled?
13
+ Rails.logger.debug("The user #{user.id} does not email enabled")
14
+ return
15
+ end
5
16
  begin
6
17
  Time.zone = user.timezone
7
18
  rescue ArgumentError
@@ -42,6 +42,12 @@ class Host::Discovered < ::Host::Base
42
42
  where(taxonomy_conditions).order("hosts.created_at DESC")
43
43
  }
44
44
 
45
+ NAMING_PATTERNS = {
46
+ 'Fact' => _('Fact + prefix'),
47
+ 'Random-name' => _('Random name'),
48
+ 'MAC-name' => _('MAC-based name')
49
+ }.freeze
50
+
45
51
  # Discovery import workflow:
46
52
  # discovered#import_host ->
47
53
  # discovered#import_facts -> base#import_facts -> base#parse_facts ->
@@ -56,16 +62,22 @@ class Host::Discovered < ::Host::Base
56
62
  raise ::Foreman::Exception.new(N_("Expected discovery_fact '%s' is missing, unable to detect primary interface and set hostname") % FacterUtils::bootif_name) unless FacterUtils::bootif_present(facts)
57
63
 
58
64
  # construct hostname
59
- prefix_from_settings = Setting[:discovery_prefix]
60
- hostname_prefix = prefix_from_settings if prefix_from_settings.present? && prefix_from_settings.match(/^[a-zA-Z].*/)
61
-
62
- name_fact = return_first_valid_fact(Setting::Discovered.discovery_hostname_fact_array, facts)
63
- raise(::Foreman::Exception.new(N_("Invalid facts: hash does not contain a valid value for any of the facts in the discovery_hostname setting: %s"), Setting::Discovered.discovery_hostname_fact_array.join(', '))) unless name_fact && name_fact.present?
64
- hostname = normalize_string_for_hostname("#{hostname_prefix}#{name_fact}")
65
+ bootif_mac = FacterUtils::bootif_mac(facts).try(:downcase)
66
+ hostname = ''
67
+ if Setting[:discovery_naming] == 'MAC-name'
68
+ hostname = NameGenerator.new.generate_next_mac_name(bootif_mac)
69
+ elsif Setting[:discovery_naming] == 'Random-name'
70
+ hostname = NameGenerator.new.generate_next_random_name
71
+ else
72
+ prefix_from_settings = Setting[:discovery_prefix]
73
+ hostname_prefix = prefix_from_settings if prefix_from_settings.present? && prefix_from_settings.match(/^[a-zA-Z].*/)
74
+ name_fact = return_first_valid_fact(Setting::Discovered.discovery_hostname_fact_array, facts)
75
+ raise(::Foreman::Exception.new(N_("Invalid facts: hash does not contain a valid value for any of the facts in the discovery_hostname setting: %s"), Setting::Discovered.discovery_hostname_fact_array.join(', '))) unless name_fact && name_fact.present?
76
+ hostname = normalize_string_for_hostname("#{hostname_prefix}#{name_fact}")
77
+ end
65
78
  Rails.logger.warn "Hostname does not start with an alphabetical character" unless hostname.downcase.match(/^[a-z]/)
66
79
 
67
80
  # check for existing managed hosts and fail or warn
68
- bootif_mac = FacterUtils::bootif_mac(facts).try(:downcase)
69
81
  existing_managed = Nic::Managed.joins(:host).where(:mac => bootif_mac, :provision => true, :hosts => {:type => "Host::Managed"}).limit(1)
70
82
  if existing_managed.count > 0
71
83
  if Setting[:discovery_error_on_existing]
@@ -131,6 +143,7 @@ class Host::Discovered < ::Host::Base
131
143
  self.discovery_attribute_set = DiscoveryAttributeSet.where(:host_id => id).first_or_create
132
144
  self.discovery_attribute_set.update_attributes(import_from_facts)
133
145
  # set additional discovery attributes
146
+ ::ForemanDiscovery::LldpNeighbors.eventually_make_bond(self) if Setting[:discovery_auto_bond]
134
147
  primary_ip = self.primary_interface.ip
135
148
  unless primary_ip.nil?
136
149
  subnet = Subnet.subnet_for(primary_ip)
@@ -17,6 +17,7 @@ class Setting::Discovered < ::Setting
17
17
  Setting.transaction do
18
18
  [
19
19
  self.set('discovery_fact', N_("Fact name to use for primary interface detection"), "discovery_bootif", N_("Interface fact")),
20
+ self.set('discovery_auto_bond', N_("Automatic bond interface (if another interface is detected on the same VLAN via LLDP)"), false, N_("Create bond interfaces")),
20
21
  self.set('discovery_clean_facts', N_("Clean all reported facts during provisioning (except discovery facts)"), false, N_("Clean all facts")),
21
22
  self.set('discovery_hostname', N_("List of facts to use for the hostname (separated by comma, first wins)"), "discovery_bootif", N_("Hostname facts")),
22
23
  self.set('discovery_auto', N_("Automatically provision newly discovered hosts, according to the provisioning rules"), false, N_("Auto provisioning")),
@@ -35,6 +36,7 @@ class Setting::Discovered < ::Setting
35
36
  self.set('discovery_pxegrub2_lock_template', N_("PXEGrub2 template to be used when pinning a host to discovery"), 'pxegrub2_discovery', N_("Locked PXEGrub2 template name"), nil, { :collection => Proc.new {Hash[ProvisioningTemplate.where(:template_kind => TemplateKind.find_by_name(:snippet)).map{|template| [template[:name], template[:name]]}]} }),
36
37
  self.set('discovery_always_rebuild_dns', N_("Force DNS entries creation when provisioning discovered host"), true, N_("Force DNS")),
37
38
  self.set('discovery_error_on_existing', N_("Do not allow to discover existing managed host matching MAC of a provisioning NIC (errors out early)"), false, N_("Error on existing NIC")),
39
+ self.set('discovery_naming', N_("Discovery hostname naming pattern"), 'Fact', N_("Type of name generator"), nil, {:collection => Proc.new {::Host::Discovered::NAMING_PATTERNS} }),
38
40
  ].compact.each { |s| self.create s.update(:category => "Setting::Discovered")}
39
41
  end
40
42
 
@@ -6,15 +6,21 @@ module ForemanDiscovery
6
6
  raise(::Foreman::Exception.new(N_("Discovered host '%{host}' has all NICs filtered out, filter: %{filter}") %
7
7
  {:host => host, :filter => Setting[:ignored_interface_identifiers]})) if interfaces.size == 0
8
8
  bootif_mac = FacterUtils::bootif_mac(facts).try(:downcase)
9
- detected = interfaces.detect { |_, values| values[:macaddress].try(:downcase) == bootif_mac }
9
+ detected = interfaces.detect { |_, values| values[:macaddress].try(:downcase) == bootif_mac && values[:ipaddress].present? }
10
10
  Rails.logger.debug "Discovery fact parser detected primary interface: #{detected}"
11
11
  # return the detected interface as array [name, facts]
12
12
  detected || raise(::Foreman::Exception.new(N_("Unable to find primary NIC with %{mac} specified via '%{fact}', NIC filter: %{filter}") %
13
13
  {:mac => bootif_mac, :fact => FacterUtils::bootif_name, :filter => Setting[:ignored_interface_identifiers]}))
14
14
  end
15
15
 
16
+ # ignores 'ignore_puppet_facts_for_provisioning' setting
16
17
  def parse_interfaces?
17
- true # to make 'ignore_puppet_facts_for_provisioning' setting non-effective
18
+ true
19
+ end
20
+
21
+ # ignores 'update_subnets_from_facts' setting
22
+ def get_facts_for_interface(interface)
23
+ super.merge(keep_subnet: true)
18
24
  end
19
25
  end
20
26
  end
@@ -0,0 +1,104 @@
1
+ module ForemanDiscovery
2
+ class LldpNeighbors
3
+ def set(iface, neighbor)
4
+ interfaces[iface] = neighbor
5
+ end
6
+
7
+ def get(iface)
8
+ interfaces[iface]
9
+ end
10
+
11
+ def list_by_pvid
12
+ list = {}
13
+ interfaces.each do |name, neighbor|
14
+ next unless neighbor.has_key? 'PVID'
15
+ vlan = neighbor['PVID']
16
+ list[vlan] = [] unless list.has_key? vlan
17
+ list[vlan].push name
18
+ end
19
+
20
+ list.each { |_, interfaces| interfaces.sort!}
21
+ list
22
+ end
23
+
24
+ def interfaces
25
+ @interfaces ||= {}
26
+ end
27
+
28
+ def get_neighbors_by_interface(ifname)
29
+ return nil unless interfaces.has_key? ifname
30
+
31
+ interface = get(ifname)
32
+ return nil unless interface.has_key? 'PVID'
33
+
34
+ list = []
35
+ interfaces.each do |name, neighbor|
36
+ next unless neighbor.has_key? 'PVID'
37
+ list.push name if neighbor['PVID'] == interface['PVID']
38
+ end
39
+
40
+ return if list.size < 2
41
+ list.sort
42
+ end
43
+
44
+ def self.eventually_make_bond(host)
45
+ primary = host.primary_interface
46
+ return if primary.nil?
47
+ return if primary.type == 'Nic::Bond'
48
+
49
+ neighbors = ::ForemanDiscovery::LldpNeighbors
50
+ .from_facts(host.facts_hash)
51
+ .get_neighbors_by_interface(primary.identifier)
52
+
53
+ return if neighbors.nil?
54
+
55
+ ip = primary.ip
56
+ mac = primary.mac
57
+ name = primary.name
58
+ primary.update(
59
+ :primary => false,
60
+ :provision => false,
61
+ :managed => false,
62
+ :name => nil,
63
+ :ip => nil
64
+ )
65
+
66
+ bond = Nic::Bond.create(
67
+ :identifier => "bond0",
68
+ :attached_devices => neighbors,
69
+ :primary => true,
70
+ :provision => true,
71
+ :name => name,
72
+ :ip => ip,
73
+ :mac => mac,
74
+ :host => host
75
+ )
76
+
77
+ bond.save!
78
+ host.interfaces.push(bond)
79
+ end
80
+
81
+ def self.from_facts(facts)
82
+ neighbors = self.new
83
+ interfaces = {}
84
+ facts.keys.each do |key|
85
+ key_s = key.to_s
86
+ next unless key_s.start_with? 'lldp_neighbor_'
87
+
88
+ property, iface = key_s[14..-1].split('_', 2)
89
+ if property == 'mngAddr'
90
+ protocol, iface = iface.split('_', 2)
91
+ property += '_' + protocol
92
+ end
93
+ interfaces[iface] = {} unless interfaces.has_key? iface
94
+ interfaces[iface][property] = facts[key]
95
+ end
96
+
97
+ interfaces.each do |name, properties|
98
+ neighbors.set name, properties
99
+ end
100
+
101
+ neighbors
102
+ end
103
+ end
104
+ end
@@ -9,7 +9,7 @@
9
9
  <th><%= _("Host Group") %></th>
10
10
  <th><%= _("Hosts/Limit") %></th>
11
11
  <th><%= sort :enabled, :as => s_("DiscoveryRule|Enabled") %></th>
12
- <th></th>
12
+ <th><%= _("Actions") %></th>
13
13
  </tr>
14
14
  <% for rule in @discovery_rules %>
15
15
  <tr>
@@ -0,0 +1,217 @@
1
+ {
2
+ "lib": "/usr/share/fdi/facts:/opt/extension/facts",
3
+ "selinux": false,
4
+ "kernelversion": "3.10.0",
5
+ "memorysize": "2.39 GB",
6
+ "memoryfree": "2.18 GB",
7
+ "swapsize": "0.00 MB",
8
+ "swapfree": "0.00 MB",
9
+ "swapsize_mb": "0.00",
10
+ "swapfree_mb": "0.00",
11
+ "memorysize_mb": "2443.68",
12
+ "memoryfree_mb": "2228.96",
13
+ "kernel": "Linux",
14
+ "hardwareisa": "x86_64",
15
+ "interfaces": "eth0,eth0_2,lo",
16
+ "macaddress_eth0": "52:54:00:00:00:99",
17
+ "mtu_eth0": 1500,
18
+ "macaddress_eth0_2": "52:54:00:00:00:99",
19
+ "mtu_eth0_2": 1500,
20
+ "ipaddress_lo": "127.0.0.1",
21
+ "ipaddress": "192.168.99.56",
22
+ "ipaddress_eth0_2": "192.168.99.56",
23
+ "netmask_lo": "255.0.0.0",
24
+ "netmask_eth0_2": "255.255.255.0",
25
+ "mtu_lo": 65536,
26
+ "uptime": "0:23 hours",
27
+ "processors": {
28
+ "models": [
29
+ "AMD Opteron 63xx class CPU",
30
+ "AMD Opteron 63xx class CPU",
31
+ "AMD Opteron 63xx class CPU",
32
+ "AMD Opteron 63xx class CPU",
33
+ "AMD Opteron 63xx class CPU",
34
+ "AMD Opteron 63xx class CPU"
35
+ ],
36
+ "count": 6,
37
+ "physicalcount": 6
38
+ },
39
+ "architecture": "x86_64",
40
+ "hardwaremodel": "x86_64",
41
+ "operatingsystem": "CentOS",
42
+ "os": {
43
+ "name": "CentOS",
44
+ "family": "RedHat",
45
+ "release": {
46
+ "major": "7",
47
+ "minor": "4",
48
+ "full": "7.4.1708"
49
+ }
50
+ },
51
+ "processor0": "AMD Opteron 63xx class CPU",
52
+ "processor1": "AMD Opteron 63xx class CPU",
53
+ "processor2": "AMD Opteron 63xx class CPU",
54
+ "processor3": "AMD Opteron 63xx class CPU",
55
+ "processor4": "AMD Opteron 63xx class CPU",
56
+ "processor5": "AMD Opteron 63xx class CPU",
57
+ "processorcount": 6,
58
+ "virtual": "kvm",
59
+ "is_virtual": true,
60
+ "vlans": "2",
61
+ "filesystems": "ext2,ext3,ext4,iso9660,squashfs",
62
+ "facterversion": "2.4.1",
63
+ "fqdn": "fdi",
64
+ "macaddress": "52:54:00:00:00:99",
65
+ "partitions": {
66
+ "vda1": {
67
+ "uuid": "86da4843-d401-45c7-95ae-f71ac60ce089",
68
+ "size": "14678016",
69
+ "filesystem": "ext4"
70
+ }
71
+ },
72
+ "kernelmajversion": "3.10",
73
+ "osfamily": "RedHat",
74
+ "path": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/opt/extension/bin:/root/bin",
75
+ "uptime_days": 0,
76
+ "netmask": "255.255.255.0",
77
+ "id": "root",
78
+ "uniqueid": "007f0200",
79
+ "network_lo": "127.0.0.0",
80
+ "network_eth0_2": "192.168.99.0",
81
+ "bios_vendor": "SeaBIOS",
82
+ "bios_version": "1.10.2-2.fc27",
83
+ "bios_release_date": "04/01/2014",
84
+ "manufacturer": "QEMU",
85
+ "productname": "Standard PC (i440FX + PIIX, 1996)",
86
+ "serialnumber": "Not Specified",
87
+ "uuid": "5F567C25-92DF-4D69-BF7B-98255E9A18D7",
88
+ "type": "Other",
89
+ "blockdevice_sr0_size": 301989888,
90
+ "blockdevice_sr0_vendor": "QEMU",
91
+ "blockdevice_sr0_model": "QEMU DVD-ROM",
92
+ "blockdevice_vda_size": 7516192768,
93
+ "blockdevice_vda_vendor": "0x1af4",
94
+ "blockdevices": "sr0,vda",
95
+ "operatingsystemrelease": "7.4.1708",
96
+ "uptime_seconds": 1426,
97
+ "rubyversion": "2.0.0",
98
+ "uptime_hours": 0,
99
+ "ps": "ps -ef",
100
+ "rubysitedir": "/usr/local/share/ruby/site_ruby/",
101
+ "operatingsystemmajrelease": "7",
102
+ "system_uptime": {
103
+ "seconds": 1426,
104
+ "hours": 0,
105
+ "days": 0,
106
+ "uptime": "0:23 hours"
107
+ },
108
+ "gid": "root",
109
+ "sshrsakey": "AAAAB3NzaC1yc2EAAAADAQABAAABAQC6wMNWRHdg9EkNyhz69xO7BEw173aAGS+h0siUeAZV1vBtUBxmMKUip03YKuOJNYyuFFM1Xoi3AvhuNau97L8lKLDwuafu/2nfb8ov6wWPpG84qSMul0Bk7ZQ2G+o6pgkKY9mQwLn65S5Cbi4u6xMRtOrv+2J6QoSXq9mIUupEKQqbrTCboIKiS6qwFkelWF2SL3Yc87dhedRsqdscgOemaBj8o3yTNswQJO9XnTT1JeSD9zj2uTNTQT2u17z3yAPmBHzBgBY2VbYj5BQfQ9AKGhxj/KsSlbCZXBksGLnMoAZl/NKnxy79fHM3pw2PPyGLsVJVEC5xJtDgTizkzSMp",
110
+ "sshfp_rsa": "SSHFP 1 1 0f09ec3c15a69053a0ac08ea419bc4647f3e7760\nSSHFP 1 2 84ba4b8589c52f74016f98d6fadafaa232f3c1b823e17d1668f88d19716c5318",
111
+ "sshecdsakey": "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLyHOqoT/QLRlOuhWpxI5eHSyWbiU7y0KmZFKVvQnajFQWvyPLyy1C3URTCozIGnJJmJiX6CgeOBSE3dQM1Yuos=",
112
+ "sshfp_ecdsa": "SSHFP 3 1 e409cb6d894d92b61f8983a1ff24fc244b0ff3e7\nSSHFP 3 2 a01e6f5f4c7d402b62d01f3af2ec594c07054c5114c004cd5e6bbd76e1bacc01",
113
+ "sshed25519key": "AAAAC3NzaC1lZDI1NTE5AAAAIGOF1jRpvPpJL92iNPUwLAZYH8EC7U8EXHggVaqj09Mp",
114
+ "sshfp_ed25519": "SSHFP 4 1 65e5525827acebb42e15ed3bbe0143d87bc07155\nSSHFP 4 2 28281c896ac18da6dd272dd239a82a03eb549a813e228cd6b0f347bda4cf01a3",
115
+ "kernelrelease": "3.10.0-693.11.1.el7.x86_64",
116
+ "rubyplatform": "x86_64-linux",
117
+ "hostname": "fdi",
118
+ "timezone": "UTC",
119
+ "physicalprocessorcount": 6,
120
+ "discovery_version": "3.4.2",
121
+ "discovery_release": "20180102.1",
122
+ "discovery_bootif": "52:54:00:00:00:99",
123
+ "link_eth0": "true",
124
+ "link_eth0_2": "true",
125
+ "link_lo": "true",
126
+ "nmprimary_connection_id": "primary",
127
+ "nmprimary_connection_uuid": "12ce9b2c-f53c-11e7-99bc-525400000099",
128
+ "nmprimary_connection_stable-id": "",
129
+ "nmprimary_connection_interface-name": "",
130
+ "nmprimary_connection_type": "vlan",
131
+ "nmprimary_connection_autoconnect": "yes",
132
+ "nmprimary_connection_autoconnect-priority": "1",
133
+ "nmprimary_connection_autoconnect-retries": "-1",
134
+ "nmprimary_connection_timestamp": "0",
135
+ "nmprimary_connection_read-only": "no",
136
+ "nmprimary_connection_permissions": "",
137
+ "nmprimary_connection_zone": "",
138
+ "nmprimary_connection_master": "",
139
+ "nmprimary_connection_slave-type": "",
140
+ "nmprimary_connection_autoconnect-slaves": "-1",
141
+ "nmprimary_connection_secondaries": "",
142
+ "nmprimary_connection_gateway-ping-timeout": "0",
143
+ "nmprimary_connection_metered": "unknown",
144
+ "nmprimary_connection_lldp": "default",
145
+ "nmprimary_802-3-ethernet_port": "",
146
+ "nmprimary_802-3-ethernet_speed": "0",
147
+ "nmprimary_802-3-ethernet_duplex": "",
148
+ "nmprimary_802-3-ethernet_auto-negotiate": "no",
149
+ "nmprimary_802-3-ethernet_mac-address": "52:54:00:00:00:99",
150
+ "nmprimary_802-3-ethernet_cloned-mac-address": "",
151
+ "nmprimary_802-3-ethernet_generate-mac-address-mask": "",
152
+ "nmprimary_802-3-ethernet_mac-address-blacklist": "",
153
+ "nmprimary_802-3-ethernet_mtu": "auto",
154
+ "nmprimary_802-3-ethernet_s390-subchannels": "",
155
+ "nmprimary_802-3-ethernet_s390-nettype": "",
156
+ "nmprimary_802-3-ethernet_s390-options": "",
157
+ "nmprimary_802-3-ethernet_wake-on-lan": "default",
158
+ "nmprimary_802-3-ethernet_wake-on-lan-password": "",
159
+ "nmprimary_ipv4_method": "auto",
160
+ "nmprimary_ipv4_dns": "",
161
+ "nmprimary_ipv4_dns-search": "",
162
+ "nmprimary_ipv4_dns-options": "",
163
+ "nmprimary_ipv4_dns-priority": "0",
164
+ "nmprimary_ipv4_addresses": "",
165
+ "nmprimary_ipv4_gateway": "",
166
+ "nmprimary_ipv4_routes": "",
167
+ "nmprimary_ipv4_route-metric": "-1",
168
+ "nmprimary_ipv4_ignore-auto-routes": "no",
169
+ "nmprimary_ipv4_ignore-auto-dns": "no",
170
+ "nmprimary_ipv4_dhcp-client-id": "",
171
+ "nmprimary_ipv4_dhcp-timeout": "300",
172
+ "nmprimary_ipv4_dhcp-send-hostname": "no",
173
+ "nmprimary_ipv4_dhcp-hostname": "",
174
+ "nmprimary_ipv4_dhcp-fqdn": "",
175
+ "nmprimary_ipv4_never-default": "no",
176
+ "nmprimary_ipv4_may-fail": "yes",
177
+ "nmprimary_ipv4_dad-timeout": "-1",
178
+ "nmprimary_ipv6_method": "ignore",
179
+ "nmprimary_ipv6_dns": "",
180
+ "nmprimary_ipv6_dns-search": "",
181
+ "nmprimary_ipv6_dns-options": "",
182
+ "nmprimary_ipv6_dns-priority": "0",
183
+ "nmprimary_ipv6_addresses": "",
184
+ "nmprimary_ipv6_gateway": "",
185
+ "nmprimary_ipv6_routes": "",
186
+ "nmprimary_ipv6_route-metric": "-1",
187
+ "nmprimary_ipv6_ignore-auto-routes": "no",
188
+ "nmprimary_ipv6_ignore-auto-dns": "no",
189
+ "nmprimary_ipv6_never-default": "no",
190
+ "nmprimary_ipv6_may-fail": "yes",
191
+ "nmprimary_ipv6_ip6-privacy": "-1",
192
+ "nmprimary_ipv6_addr-gen-mode": "eui64",
193
+ "nmprimary_ipv6_dhcp-send-hostname": "yes",
194
+ "nmprimary_ipv6_dhcp-hostname": "",
195
+ "nmprimary_ipv6_token": "",
196
+ "nmprimary_vlan_parent": "",
197
+ "nmprimary_vlan_id": "2",
198
+ "nmprimary_vlan_flags": "1",
199
+ "nmprimary_vlan_ingress-priority-map": "",
200
+ "nmprimary_vlan_egress-priority-map": "",
201
+ "nmprimary_proxy_method": "none",
202
+ "nmprimary_proxy_browser-only": "no",
203
+ "nmprimary_proxy_pac-url": "",
204
+ "nmprimary_proxy_pac-script": "",
205
+ "nmprimary_general_name": "primary",
206
+ "nmprimary_general_uuid": "12ce9b2c-f53c-11e7-99bc-525400000099",
207
+ "nmprimary_general_devices": "eth0.2",
208
+ "nmprimary_general_state": "activating",
209
+ "nmprimary_general_default": "no",
210
+ "nmprimary_general_default6": "no",
211
+ "nmprimary_general_vpn": "no",
212
+ "nmprimary_general_zone": "",
213
+ "nmprimary_general_dbus-path": "/org/freedesktop/NetworkManager/ActiveConnection/3",
214
+ "nmprimary_general_con-path": "/org/freedesktop/NetworkManager/Settings/2",
215
+ "nmprimary_general_spec-object": "",
216
+ "nmprimary_general_master-path": ""
217
+ }