boris 1.0.0.beta.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.
- data/LICENSE.md +9 -0
- data/README.md +94 -0
- data/boris.gemspec +28 -0
- data/doc/Array.html +437 -0
- data/doc/Boris.html +230 -0
- data/doc/Boris/ConnectionAlreadyActive.html +123 -0
- data/doc/Boris/ConnectionFailed.html +127 -0
- data/doc/Boris/Connector.html +794 -0
- data/doc/Boris/InvalidCredentials.html +131 -0
- data/doc/Boris/InvalidOption.html +123 -0
- data/doc/Boris/InvalidTargetName.html +123 -0
- data/doc/Boris/Lumberjack.html +466 -0
- data/doc/Boris/MissingCredentials.html +123 -0
- data/doc/Boris/NoActiveConnection.html +123 -0
- data/doc/Boris/NoProfileDetected.html +123 -0
- data/doc/Boris/Options.html +783 -0
- data/doc/Boris/Profiles.html +117 -0
- data/doc/Boris/Profiles/Linux.html +1151 -0
- data/doc/Boris/Profiles/RedHat.html +875 -0
- data/doc/Boris/Profiles/Solaris.html +1230 -0
- data/doc/Boris/Profiles/Structure.html +2050 -0
- data/doc/Boris/Profiles/UNIX.html +893 -0
- data/doc/Boris/Profiles/Windows.html +1846 -0
- data/doc/Boris/Profiles/Windows/Windows2003.html +304 -0
- data/doc/Boris/Profiles/Windows/Windows2008.html +379 -0
- data/doc/Boris/Profiles/Windows/Windows2012.html +304 -0
- data/doc/Boris/SNMPConnector.html +512 -0
- data/doc/Boris/SSHConnector.html +633 -0
- data/doc/Boris/Target.html +2002 -0
- data/doc/Boris/WMIConnector.html +1134 -0
- data/doc/BorisLogger.html +217 -0
- data/doc/Hash.html +195 -0
- data/doc/String.html +1246 -0
- data/doc/_index.html +420 -0
- data/doc/class_list.html +53 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +57 -0
- data/doc/css/style.css +328 -0
- data/doc/file.README.html +183 -0
- data/doc/file_list.html +55 -0
- data/doc/frames.html +28 -0
- data/doc/index.html +183 -0
- data/doc/js/app.js +214 -0
- data/doc/js/full_list.js +173 -0
- data/doc/js/jquery.js +4 -0
- data/doc/method_list.html +1468 -0
- data/doc/top-level-namespace.html +126 -0
- data/lib/boris.rb +30 -0
- data/lib/boris/connectors.rb +47 -0
- data/lib/boris/connectors/snmp.rb +56 -0
- data/lib/boris/connectors/ssh.rb +110 -0
- data/lib/boris/connectors/wmi.rb +186 -0
- data/lib/boris/errors.rb +17 -0
- data/lib/boris/helpers/array.rb +63 -0
- data/lib/boris/helpers/constants.rb +20 -0
- data/lib/boris/helpers/hash.rb +8 -0
- data/lib/boris/helpers/scrubber.rb +51 -0
- data/lib/boris/helpers/string.rb +130 -0
- data/lib/boris/lumberjack.rb +47 -0
- data/lib/boris/options.rb +86 -0
- data/lib/boris/profiles/linux/redhat.rb +77 -0
- data/lib/boris/profiles/linux_core.rb +216 -0
- data/lib/boris/profiles/unix/solaris.rb +307 -0
- data/lib/boris/profiles/unix_core.rb +85 -0
- data/lib/boris/profiles/windows/windows2003.rb +15 -0
- data/lib/boris/profiles/windows/windows2008.rb +23 -0
- data/lib/boris/profiles/windows/windows2012.rb +15 -0
- data/lib/boris/profiles/windows_core.rb +530 -0
- data/lib/boris/structure.rb +167 -0
- data/lib/boris/target.rb +340 -0
- data/test/connector_tests/test_snmp.rb +35 -0
- data/test/connector_tests/test_ssh.rb +51 -0
- data/test/connector_tests/test_wmi.rb +129 -0
- data/test/helper_tests/test_array.rb +25 -0
- data/test/helper_tests/test_hash.rb +10 -0
- data/test/helper_tests/test_string.rb +136 -0
- data/test/profile_tests/test_core_skeleton +107 -0
- data/test/profile_tests/test_linux_core.rb +331 -0
- data/test/profile_tests/test_redhat.rb +134 -0
- data/test/profile_tests/test_solaris.rb +523 -0
- data/test/profile_tests/test_unix_core.rb +117 -0
- data/test/profile_tests/test_windows.rb +536 -0
- data/test/setup_tests.rb +14 -0
- data/test/test_all.rb +8 -0
- data/test/test_options.rb +44 -0
- data/test/test_structure.rb +136 -0
- data/test/test_target.rb +146 -0
- metadata +241 -0
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'setup_tests'
|
2
|
+
|
3
|
+
class UNIXCoreTest < ProfileTestSetup
|
4
|
+
context 'a UNIX target' do
|
5
|
+
setup do
|
6
|
+
@connector = @target.connector = instance_of(SSHConnector)
|
7
|
+
@target.stubs(:target_profile).returns(Profiles::UNIX)
|
8
|
+
@target.extend(Profiles::UNIX)
|
9
|
+
@connector.stubs(:value_at).with('uname -a').returns('some_flavor_of_unix')
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'being scanned' do
|
13
|
+
setup do
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'for file system information' do
|
17
|
+
setup do
|
18
|
+
@file_system_data = [
|
19
|
+
'/dev/md/dsk/d10|1000|500|/',
|
20
|
+
'/dev/md/dsk/d11|2000|1000|/var'
|
21
|
+
]
|
22
|
+
|
23
|
+
@expected_data = [
|
24
|
+
{
|
25
|
+
:capacity_mb=>1000,
|
26
|
+
:file_system=>'/dev/md/dsk/d10',
|
27
|
+
:mount_point=>'/',
|
28
|
+
:san_storage=>nil,
|
29
|
+
:used_space_mb=>500
|
30
|
+
},
|
31
|
+
{
|
32
|
+
:capacity_mb=>2000,
|
33
|
+
:file_system=>'/dev/md/dsk/d11',
|
34
|
+
:mount_point=>'/var',
|
35
|
+
:san_storage=>nil,
|
36
|
+
:used_space_mb=>1000
|
37
|
+
}
|
38
|
+
]
|
39
|
+
end
|
40
|
+
|
41
|
+
should 'return file system information via #get_file_systems' do
|
42
|
+
file_system_command = %q{df -kl 2>/dev/null | grep ^/ | nawk '{print $1 "|" $2 / 1024 "|" $3 / 1024 "|" $6}'}
|
43
|
+
|
44
|
+
@connector.stubs(:values_at).with(file_system_command).returns(@file_system_data)
|
45
|
+
|
46
|
+
@target.get_file_systems
|
47
|
+
|
48
|
+
assert_equal(@expected_data, @target.file_systems)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# OS SPECIFIC
|
53
|
+
#context 'for hardware information' do
|
54
|
+
#end
|
55
|
+
|
56
|
+
# OS SPECIFIC
|
57
|
+
#context 'for hosted shares' do
|
58
|
+
#end
|
59
|
+
|
60
|
+
# OS SPECIFIC
|
61
|
+
#context 'for installed applications' do
|
62
|
+
#end
|
63
|
+
|
64
|
+
# OS SPECIFIC
|
65
|
+
#context 'for installed patches' do
|
66
|
+
#end
|
67
|
+
|
68
|
+
# OS SPECIFIC
|
69
|
+
#context 'for installed services' do
|
70
|
+
#end
|
71
|
+
|
72
|
+
context 'for local users and groups' do
|
73
|
+
setup do
|
74
|
+
@user_data = [
|
75
|
+
'root:x:0:0:Super-User:/root:/sbin/sh',
|
76
|
+
'usera:x:2001:10:User A:/export/home/usera:/bin/ksh',
|
77
|
+
'userb:x:2001:10:User B:/export/home/userb:/bin/ksh'
|
78
|
+
]
|
79
|
+
@group_data = ['root::0:', 'staff::10:']
|
80
|
+
@expected_data = [{:members=>['root'], :name=>'root'}, {:members=>['usera', 'userb'], :name=>'staff'}]
|
81
|
+
end
|
82
|
+
|
83
|
+
should 'return local user groups and accounts via #get_local_user_groups' do
|
84
|
+
@connector.stubs(:values_at).with('cat /etc/passwd | grep -v "^#"').returns(@user_data)
|
85
|
+
@connector.stubs(:values_at).with('cat /etc/group | grep -v "^#"').returns(@group_data)
|
86
|
+
|
87
|
+
@target.get_local_user_groups
|
88
|
+
|
89
|
+
assert_equal(@expected_data, @target.local_user_groups)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'for network identification' do
|
94
|
+
setup do
|
95
|
+
@expected_data = {:domain=>'mydomain.com', :hostname=>'SERVER01'}
|
96
|
+
end
|
97
|
+
|
98
|
+
should 'return the domain and hostname via #get_network_id' do
|
99
|
+
@connector.stubs(:value_at).with('hostname').returns(@expected_data[:hostname])
|
100
|
+
@connector.stubs(:value_at).with('domainname').returns(@expected_data[:domain])
|
101
|
+
|
102
|
+
@target.get_network_id
|
103
|
+
|
104
|
+
assert_equal(@expected_data, @target.network_id)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# OS SPECIFIC
|
109
|
+
#context 'for network interfaces' do; end
|
110
|
+
#end
|
111
|
+
|
112
|
+
# OS SPECIFIC
|
113
|
+
#context 'for operating system information' do
|
114
|
+
#end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,536 @@
|
|
1
|
+
require 'setup_tests'
|
2
|
+
|
3
|
+
class WindowsCoreTest < ProfileTestSetup
|
4
|
+
extend Profiles::Structure
|
5
|
+
|
6
|
+
context 'a Windows target' do
|
7
|
+
setup do
|
8
|
+
@connector = @target.connector = instance_of(WMIConnector)
|
9
|
+
@target.stubs(:target_profile).returns(Profiles::Windows)
|
10
|
+
@target.extend(Profiles::Windows)
|
11
|
+
@connector.stubs(:value_at).with('SELECT Name FROM Win32_OperatingSystem').returns({:name=>'Windows Server 2008'})
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'being scanned' do
|
15
|
+
setup do
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'for file system information' do
|
19
|
+
setup do
|
20
|
+
@logical_disks_qry = 'SELECT FreeSpace, Name, Size FROM Win32_LogicalDisk WHERE DriveType=3'
|
21
|
+
@logical_disks_data = [
|
22
|
+
{:freespace=>1024, :name=>'C:', :size=>2048}
|
23
|
+
]
|
24
|
+
|
25
|
+
@physical_disks_qry = 'SELECT DeviceID, Model FROM Win32_DiskDrive'
|
26
|
+
@physical_disks_data = [
|
27
|
+
{
|
28
|
+
:deviceid=>'\\.\PHYSICALDRIVE0',
|
29
|
+
:model=>'LOGICAL VOLUME SCSI Disk Device'
|
30
|
+
}
|
31
|
+
]
|
32
|
+
|
33
|
+
@partition_mapping_qry = 'SELECT Antecedent, Dependent FROM Win32_LogicalDiskToPartition'
|
34
|
+
@partition_mapping_data = [
|
35
|
+
{
|
36
|
+
:antecedent=>"\\#{@target_name}\\root\\cimv2:Win32_DiskPartition.DeviceID=\"Disk #0, Partition #0\"",
|
37
|
+
:dependent=>"\\#{@target_name}\\root\\cimv2:Win32_LogicalDisk.DeviceID=\"C:\""
|
38
|
+
}
|
39
|
+
]
|
40
|
+
|
41
|
+
@disk_partitions_qry = "SELECT Antecedent, Dependent FROM Win32_DiskDriveToDiskPartition"
|
42
|
+
@disk_partitions_data = [
|
43
|
+
{
|
44
|
+
:antecedent=>"\\#{@target_name}\\root\\cimv2:Win32_DiskDrive.DeviceID=\"\\\\.\\PHYSICALDRIVE0\"",
|
45
|
+
:dependent=>"\\#{@target_name}\\root\\cimv2:Win32_DiskPartition.DeviceID=\"Disk #0, Partition #0\""
|
46
|
+
}
|
47
|
+
]
|
48
|
+
|
49
|
+
@expected_data = [
|
50
|
+
{
|
51
|
+
:capacity_mb=>2,
|
52
|
+
:file_system=>'Disk #0, Partition #0',
|
53
|
+
:mount_point=>'C:',
|
54
|
+
:san_storage=>nil,
|
55
|
+
:used_space_mb=>1
|
56
|
+
}
|
57
|
+
]
|
58
|
+
end
|
59
|
+
|
60
|
+
should 'return file system information via #get_file_systems' do
|
61
|
+
@connector.stubs(:values_at).with(@logical_disks_qry).returns(@logical_disks_data)
|
62
|
+
@connector.stubs(:values_at).with(@partition_mapping_qry).returns(@partition_mapping_data)
|
63
|
+
@connector.stubs(:values_at).with(@physical_disks_qry).returns(@physical_disks_data)
|
64
|
+
@connector.stubs(:values_at).with(@disk_partitions_qry).returns(@disk_partitions_data)
|
65
|
+
|
66
|
+
@target.get_file_systems
|
67
|
+
|
68
|
+
assert_equal(@expected_data, @target.file_systems)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'for hardware information' do
|
73
|
+
setup do
|
74
|
+
@bios_qry = 'SELECT SerialNumber, SMBIOSBIOSVersion FROM Win32_BIOS'
|
75
|
+
@bios_data = {:serialnumber=>'1234ABCD', :smbiosbiosversion=>'6.0'}
|
76
|
+
|
77
|
+
@model_qry = 'SELECT Manufacturer, Model, TotalPhysicalMemory FROM Win32_ComputerSystem'
|
78
|
+
@model_data = {
|
79
|
+
:manufacturer=>'VMware, Inc.',
|
80
|
+
:model=>'VMware Virtual Platform',
|
81
|
+
:totalphysicalmemory=>2146861056
|
82
|
+
}
|
83
|
+
|
84
|
+
@cpu_qry = 'SELECT * FROM Win32_Processor'
|
85
|
+
@cpu_data = [
|
86
|
+
{
|
87
|
+
:datawidth=>32,
|
88
|
+
:l2cachesize=>1024,
|
89
|
+
:manufacturer=>'AuthenticAMD',
|
90
|
+
:maxclockspeed=>2813,
|
91
|
+
:name=>'Dual-Core AMD Opteron(tm) Processor 8220',
|
92
|
+
:numberofcores=>1,
|
93
|
+
:numberoflogicalprocessors=>1
|
94
|
+
}
|
95
|
+
]
|
96
|
+
|
97
|
+
@expected_data = {
|
98
|
+
:cpu_architecture=>32,
|
99
|
+
:cpu_core_count=>1,
|
100
|
+
:cpu_model=>'Dual-Core AMD Opteron(tm) Processor 8220',
|
101
|
+
:cpu_physical_count=>1,
|
102
|
+
:cpu_speed_mhz=>2813,
|
103
|
+
:cpu_vendor=>'AuthenticAMD',
|
104
|
+
:firmware_version=>'6.0',
|
105
|
+
:model=>'VMware Virtual Platform',
|
106
|
+
:memory_installed_mb=>2047,
|
107
|
+
:serial=>'1234ABCD',
|
108
|
+
:vendor=>'VMware, Inc.'
|
109
|
+
}
|
110
|
+
end
|
111
|
+
|
112
|
+
should 'return hardware information via #get_hardware' do
|
113
|
+
@connector.stubs(:value_at).with(@bios_qry).returns(@bios_data)
|
114
|
+
@connector.stubs(:value_at).with(@model_qry).returns(@model_data)
|
115
|
+
@connector.stubs(:values_at).with(@cpu_qry).returns(@cpu_data)
|
116
|
+
|
117
|
+
@target.get_hardware
|
118
|
+
|
119
|
+
assert_equal(@expected_data, @target.hardware)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context 'for hosted shares' do
|
124
|
+
setup do
|
125
|
+
@expected_data = [{:name=>'myshare', :path=>'D:\myshare'}]
|
126
|
+
end
|
127
|
+
|
128
|
+
should 'return hosted share information via #get_hosted_shares' do
|
129
|
+
@connector.stubs(:values_at).with('SELECT Name, Path FROM Win32_Share WHERE Type = 0').returns(@expected_data)
|
130
|
+
@target.get_hosted_shares
|
131
|
+
assert_equal(@expected_data, @target.hosted_shares)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context 'for installed applications' do
|
136
|
+
setup do
|
137
|
+
@guid = '{4AB6A079-178B-4144-B21F-4D1AE71666A2}'
|
138
|
+
@product_key_binary = [164, 1, 1, 0, 3, 0, 0, 0, 53, 53, 48, 52, 49, 45, 49, 56, 54, 45, 48, 49, 51, 51, 48,
|
139
|
+
51, 53, 45, 55, 53, 55, 54, 51, 0, 151, 0, 0, 0, 88, 49, 52, 45, 50, 51, 56, 57, 54, 0, 0, 0, 0, 0, 0, 0,
|
140
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
141
|
+
@expected_product_key = 'BBBBB-BBBBB-BBBBB-BBBBB-BBBBB'
|
142
|
+
end
|
143
|
+
|
144
|
+
should 'extract the product key from a binary string' do
|
145
|
+
assert_equal(@expected_product_key, @product_key_binary.to_ms_product_key)
|
146
|
+
end
|
147
|
+
|
148
|
+
context 'by microsoft' do
|
149
|
+
context 'in the sqlserver family' do
|
150
|
+
should 'detect the product key for various sqlserver editions' do
|
151
|
+
|
152
|
+
versions = []
|
153
|
+
versions << {:code=>90, :instance=>'mssql.1', :name=>'Microsoft SQL Server 2005'}
|
154
|
+
versions << {:code=>100, :instance=>'mssql10.1', :name=>'Microsoft SQL Server 2008'}
|
155
|
+
versions << {:code=>110, :instance=>'mssql11.1', :name=>'Microsoft SQL Server 2012'}
|
156
|
+
|
157
|
+
key_path = 'SOFTWARE\Microsoft\Microsoft SQL Server'
|
158
|
+
|
159
|
+
versions.each do |version|
|
160
|
+
@connector.stubs(:registry_subkeys_at).returns(["#{key_path}\\#{version[:instance]}"])
|
161
|
+
@connector.stubs(:registry_values_at).with("#{key_path}\\#{version[:code]}\\ProductID").returns({:digitalproductid=>@product_key_binary})
|
162
|
+
assert_equal(@expected_product_key, @target.get_product_key(version[:name]))
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
context 'in the visual studio family' do
|
168
|
+
setup do
|
169
|
+
@connector.stubs(:registry_values_at).at_least_once.returns({:pidkey=>@expected_product_key.gsub(/-/, '')})
|
170
|
+
end
|
171
|
+
|
172
|
+
should 'detect the product key for various Visual Studio editions' do
|
173
|
+
assert_equal(@expected_product_key, @target.get_product_key('Microsoft Visual Studio 2005 Professional Edition'))
|
174
|
+
assert_equal(@expected_product_key, @target.get_product_key('Microsoft Visual Studio 2008 Professional Edition'))
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
context "in the exchange/office/windows families" do
|
179
|
+
setup do
|
180
|
+
@connector.stubs(:registry_values_at).at_least_once.returns({:digitalproductid=>@product_key_binary})
|
181
|
+
end
|
182
|
+
|
183
|
+
should 'detect the product key for various Exchange editions' do
|
184
|
+
assert_equal(@expected_product_key, @target.get_product_key('Microsoft Exchange'))
|
185
|
+
end
|
186
|
+
|
187
|
+
should 'detect the product key for various Office and Exchange editions' do
|
188
|
+
assert_equal(@expected_product_key, @target.get_product_key('Microsoft Office Professional Edition 2003', @guid))
|
189
|
+
assert_equal(@expected_product_key, @target.get_product_key('Microsoft Office Project Server 12', @guid))
|
190
|
+
assert_equal(@expected_product_key, @target.get_product_key('Microsoft Office SharePoint Server 2007', @guid))
|
191
|
+
assert_equal(@expected_product_key, @target.get_product_key('Microsoft Office XP Professional with FrontPage', @guid))
|
192
|
+
end
|
193
|
+
|
194
|
+
should 'detect the product key for various Windows editions' do
|
195
|
+
assert_equal(@expected_product_key, @target.get_product_key('Microsoft Windows'))
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
should 'return installed applications via #get_installed_applications' do
|
201
|
+
key_path = Profiles::Windows::APP64_KEYPATH + '\{4AB6A079-178B-4144-B21F-4D1AE71666A2}'
|
202
|
+
|
203
|
+
application_data = {
|
204
|
+
:installdate=>'20120101',
|
205
|
+
:installlocation=>'',
|
206
|
+
:displayname=>'Microsoft SQL Server 2008 R2 Native Client',
|
207
|
+
:publisher=>'Microsoft Corporation',
|
208
|
+
:displayversion=>'10.50.1600.1'
|
209
|
+
}
|
210
|
+
|
211
|
+
expected_data = {
|
212
|
+
:date_installed=>DateTime.parse(application_data[:installdate]),
|
213
|
+
:install_location=>nil,
|
214
|
+
:license_key=>nil,
|
215
|
+
:name=>application_data[:displayname],
|
216
|
+
:vendor=>application_data[:publisher],
|
217
|
+
:version=>application_data[:displayversion]
|
218
|
+
}
|
219
|
+
|
220
|
+
@connector.stubs(:registry_subkeys_at).with(Profiles::Windows::ORACLE_KEYPATH).returns([])
|
221
|
+
|
222
|
+
@connector.stubs(:registry_subkeys_at).with(Profiles::Windows::APP32_KEYPATH).returns([])
|
223
|
+
@connector.stubs(:registry_subkeys_at).with(Profiles::Windows::APP64_KEYPATH).returns([key_path])
|
224
|
+
|
225
|
+
sql_key_path = 'SOFTWARE\Microsoft\Microsoft SQL Server'
|
226
|
+
@connector.stubs(:registry_subkeys_at).with(sql_key_path).returns(["#{sql_key_path}\\mssql10.1"])
|
227
|
+
@connector.stubs(:registry_values_at).with("#{sql_key_path}\\100\\ProductID").returns({})
|
228
|
+
@connector.stubs(:registry_values_at).with("#{sql_key_path}\\Setup").returns({})
|
229
|
+
@connector.stubs(:registry_values_at).with(key_path).returns(application_data)
|
230
|
+
|
231
|
+
@target.get_installed_applications
|
232
|
+
|
233
|
+
assert_equal([expected_data], @target.installed_applications)
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
context 'for installed patches' do
|
238
|
+
should 'parse out the patches from the registry location for applications' do
|
239
|
+
wmi_patch_data = {
|
240
|
+
:hotfixid=>'KB456789',
|
241
|
+
:installedby=>'SYSTEM',
|
242
|
+
:installedon=>'1/1/2013',
|
243
|
+
:servicepackineffect=>''
|
244
|
+
}
|
245
|
+
|
246
|
+
registry_patch_data = {
|
247
|
+
:displayname=>'KB123456',
|
248
|
+
:displayversion=>'1.0',
|
249
|
+
:installdate=>'20120101',
|
250
|
+
:installlocation=>'',
|
251
|
+
:publisher=>'Microsoft Corporation'
|
252
|
+
}
|
253
|
+
registry_patch_key_path = "#{Profiles::Windows::APP32_KEYPATH}\\#{registry_patch_data[:displayname]}"
|
254
|
+
|
255
|
+
expected_data = [
|
256
|
+
{:date_installed=>DateTime.parse(wmi_patch_data[:installedon]), :installed_by=>wmi_patch_data[:installedby], :patch_code=>wmi_patch_data[:hotfixid]},
|
257
|
+
{:date_installed=>DateTime.parse(registry_patch_data[:installdate]), :installed_by=>nil, :patch_code=>registry_patch_data[:displayname]}
|
258
|
+
]
|
259
|
+
|
260
|
+
@connector.stubs(:values_at).returns([wmi_patch_data])
|
261
|
+
|
262
|
+
@connector.stubs(:registry_subkeys_at).with(Profiles::Windows::APP32_KEYPATH).returns([registry_patch_key_path])
|
263
|
+
@connector.stubs(:registry_subkeys_at).with(Profiles::Windows::APP64_KEYPATH).returns([])
|
264
|
+
@connector.stubs(:registry_values_at).with(registry_patch_key_path).returns(registry_patch_data)
|
265
|
+
|
266
|
+
@target.get_installed_patches
|
267
|
+
|
268
|
+
assert_equal(expected_data, @target.installed_patches)
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
context 'for installed services' do
|
273
|
+
setup do
|
274
|
+
@service_data = [
|
275
|
+
:name=>'Plug and Play',
|
276
|
+
:pathname=>'C:\WINDOWS\system32\services.exe',
|
277
|
+
:startmode=>'Auto'
|
278
|
+
]
|
279
|
+
|
280
|
+
@expected_data = [{
|
281
|
+
:name=>'Plug and Play',
|
282
|
+
:install_location=>'C:\WINDOWS\system32\services.exe',
|
283
|
+
:start_mode=>'Auto'
|
284
|
+
}]
|
285
|
+
end
|
286
|
+
|
287
|
+
should 'return service information via #get_installed_services' do
|
288
|
+
@connector.stubs(:values_at).with('SELECT Name, PathName, StartMode FROM Win32_Service').returns(@service_data)
|
289
|
+
|
290
|
+
@target.get_installed_services
|
291
|
+
assert_equal(@expected_data, @target.installed_services)
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
|
296
|
+
context 'for local users and groups' do
|
297
|
+
should 'allow us to detect the user name of an account from its guid via #get_username' do
|
298
|
+
user_data = {:caption=>'username', :sid=>'S-1-1-1'}
|
299
|
+
|
300
|
+
@connector.stubs(:value_at).with("SELECT Caption, SID FROM Win32_UserAccount WHERE SID = '#{user_data[:sid]}'").returns(user_data)
|
301
|
+
|
302
|
+
assert_equal(user_data[:caption], @target.get_username(user_data[:sid]))
|
303
|
+
end
|
304
|
+
|
305
|
+
should 'return local user groups and accounts via #get_local_user_groups if the server is not a domain controller' do
|
306
|
+
hostname = 'SERVER01'
|
307
|
+
group = 'Users'
|
308
|
+
members = ["#{hostname}\\user1", "#{hostname}\\user2"]
|
309
|
+
|
310
|
+
wmi_member_data = [
|
311
|
+
{:partcomponent=>"\\#{hostname}\root\cimv2:Win32_UserAccount.Domain=\"#{hostname}\",Name=\"user1\""},
|
312
|
+
{:partcomponent=>"\\#{hostname}\root\cimv2:Win32_UserAccount.Domain=\"#{hostname}\",Name=\"user2\""}
|
313
|
+
]
|
314
|
+
|
315
|
+
expected_data = [{:name=>group, :members=>members}]
|
316
|
+
|
317
|
+
@target.instance_variable_set(:@network_id, {:domain=>'mydomain.com', :hostname=>hostname})
|
318
|
+
|
319
|
+
@connector.stubs(:value_at).with('SELECT Roles FROM Win32_ComputerSystem').returns({:roles=>[]})
|
320
|
+
|
321
|
+
@connector.stubs(:values_at).with("SELECT Name FROM Win32_Group WHERE Domain = '#{hostname}'").returns([{:name=>'Users'}])
|
322
|
+
@connector.stubs(:values_at).with("SELECT * FROM Win32_GroupUser WHERE GroupComponent = \"Win32_Group.Domain='#{hostname}',Name='#{group}'\"").returns(wmi_member_data)
|
323
|
+
|
324
|
+
@target.get_local_user_groups
|
325
|
+
|
326
|
+
assert_equal(expected_data, @target.local_user_groups)
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
context 'for network identification' do
|
331
|
+
setup do
|
332
|
+
@expected_data = {:domain=>'mydomain.com', :name=>'SERVER01'}
|
333
|
+
end
|
334
|
+
|
335
|
+
should 'return the domain and hostname via #get_network_id' do
|
336
|
+
@connector.stubs(:value_at).with('SELECT Domain, Name FROM Win32_ComputerSystem').returns(@expected_data)
|
337
|
+
@target.get_network_id
|
338
|
+
|
339
|
+
assert_equal(@target.network_id[:domain], @expected_data[:domain])
|
340
|
+
assert_equal(@target.network_id[:hostname], @expected_data[:name])
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
context 'for network interfaces' do
|
345
|
+
setup do
|
346
|
+
@expected_ethernet_data = [@target.network_interface_template.merge({
|
347
|
+
:auto_negotiate=>false,
|
348
|
+
:current_speed_mbps=>1000,
|
349
|
+
:dns_servers=>['192.168.1.100', '192.168.1.101'],
|
350
|
+
:duplex=>'full',
|
351
|
+
:ip_addresses=>[{:ip_address=>'192.168.1.2', :subnet=>'255.255.255.0'}],
|
352
|
+
:is_uplink=>false,
|
353
|
+
:mac_address=>'01:01:01:01:01:01',
|
354
|
+
:model=>'Intel PRO/1000',
|
355
|
+
:model_id=>'0x1234',
|
356
|
+
:mtu=>1400,
|
357
|
+
:name=>'Local Area Connection',
|
358
|
+
:status=>'up',
|
359
|
+
:type=>'ethernet',
|
360
|
+
:vendor=>'Intel Corp.',
|
361
|
+
:vendor_id=>'0x1234'
|
362
|
+
})]
|
363
|
+
|
364
|
+
@expected_fibre_data = @target.network_interface_template.merge({
|
365
|
+
:current_speed_mbps=>4000,
|
366
|
+
:fabric_name=>'00000000aaaaaaaa',
|
367
|
+
:is_uplink=>false,
|
368
|
+
:model=>'QLogic Fibre Channel Adapter',
|
369
|
+
:model_id=>'0x1234',
|
370
|
+
:name=>'fc0',
|
371
|
+
:node_wwn=>'00000000aaaaaaaa',
|
372
|
+
:port_wwn=>'00000000aaaaaaaa',
|
373
|
+
:status=>'up',
|
374
|
+
:type=>'fibre',
|
375
|
+
:vendor=>'QLogic Corp.',
|
376
|
+
:vendor_id=>'0x1234'
|
377
|
+
})
|
378
|
+
end
|
379
|
+
|
380
|
+
should 'return ethernet interface information via #get_network_interfaces' do
|
381
|
+
|
382
|
+
expected_ethernet_data = @expected_ethernet_data[0]
|
383
|
+
|
384
|
+
@connector.stubs(:values_at).with('SELECT InstanceName, Manufacturer, ModelDescription FROM MSFC_FCAdapterHBAAttributes', :root_wmi).returns([])
|
385
|
+
@connector.stubs(:values_at).with('SELECT Attributes, InstanceName FROM MSFC_FibrePortHBAAttributes', :root_wmi).returns([])
|
386
|
+
|
387
|
+
ethernet_guid = '{1234ABCD}'
|
388
|
+
nic_keypath = Profiles::Windows::NIC_CFG_KEYPATH
|
389
|
+
ethernet_data = [{
|
390
|
+
:index=>1,
|
391
|
+
:macaddress=>expected_ethernet_data[:mac_address],
|
392
|
+
:manufacturer=>expected_ethernet_data[:vendor],
|
393
|
+
:netconnectionid=>expected_ethernet_data[:name],
|
394
|
+
:netconnectionstatus=>2,
|
395
|
+
:productname=>expected_ethernet_data[:model]
|
396
|
+
}]
|
397
|
+
|
398
|
+
@connector.stubs(:values_at).with('SELECT Index, MACAddress, Manufacturer, NetConnectionID, NetConnectionStatus, ProductName FROM Win32_NetworkAdapter WHERE NetConnectionID IS NOT NULL').returns(ethernet_data)
|
399
|
+
|
400
|
+
adapter_config_data = {
|
401
|
+
:dnsserversearchorder=>expected_ethernet_data[:dns_servers],
|
402
|
+
:ipaddress=>expected_ethernet_data[:ip_addresses].collect{|ip| ip[:ip_address]},
|
403
|
+
:ipsubnet=>expected_ethernet_data[:ip_addresses].collect{|ip| ip[:subnet]}[0],
|
404
|
+
:settingid=>ethernet_guid
|
405
|
+
}
|
406
|
+
@connector.stubs(:value_at).with("SELECT DNSServerSearchOrder, IPAddress, IPSubnet, SettingID FROM Win32_NetworkAdapterConfiguration WHERE Index = #{ethernet_data[0][:index]}").returns(adapter_config_data)
|
407
|
+
|
408
|
+
enum_adapter_data = {:devicename=>"\\DEVICE\\#{ethernet_guid}", :instancename=>expected_ethernet_data[:model]}
|
409
|
+
|
410
|
+
nic_cfg_path = nic_keypath + "\\0001"
|
411
|
+
|
412
|
+
@connector.stubs(:registry_values_at).with(nic_cfg_path + '\\Linkage').returns(:export=>[enum_adapter_data[:devicename]])
|
413
|
+
@connector.stubs(:registry_values_at).with(nic_cfg_path).returns({:matchingdeviceid=>'pci\\ven_1234&dev_1234', :speedduplex=>1})
|
414
|
+
@connector.stubs(:registry_subkeys_at).with(nic_cfg_path + "\\Ndi\\params").returns([nic_cfg_path + '\\SpeedDuplex'])
|
415
|
+
@connector.stubs(:registry_values_at).with(nic_cfg_path + "\\Ndi\\params\\speedduplex\\Enum").returns({'1'.to_sym=>'1000Mbps/Full Duplex'})
|
416
|
+
|
417
|
+
@connector.stubs(:value_at).with("SELECT InstanceName FROM MSNdis_EnumerateAdapter WHERE DeviceName = '#{enum_adapter_data[:devicename].gsub(/\\/, '\\\\\\')}'", :root_wmi).returns(enum_adapter_data)
|
418
|
+
linkspeed_data = {:instancename=>expected_ethernet_data[:model], :ndislinkspeed=>10000000}
|
419
|
+
@connector.stubs(:value_at).with("SELECT NdisLinkSpeed FROM MSNdis_LinkSpeed WHERE InstanceName = '#{expected_ethernet_data[:model]}'", :root_wmi).returns(linkspeed_data)
|
420
|
+
|
421
|
+
@connector.stubs(:registry_values_at).with(Profiles::Windows::TCPIP_CFG_KEYPATH + "\\#{ethernet_guid}").returns({:mtu=>1400})
|
422
|
+
|
423
|
+
@target.get_network_interfaces
|
424
|
+
assert_equal(@expected_ethernet_data, @target.network_interfaces)
|
425
|
+
end
|
426
|
+
|
427
|
+
should 'return fibre channel interface information via #get_network_interfaces' do
|
428
|
+
@connector.stubs(:values_at).with('SELECT Index, MACAddress, Manufacturer, NetConnectionID, NetConnectionStatus, ProductName FROM Win32_NetworkAdapter WHERE NetConnectionID IS NOT NULL').returns([])
|
429
|
+
|
430
|
+
hba_data = {
|
431
|
+
:instancename=>'pci\\ven_1234&dev_1234',
|
432
|
+
:manufacturer=>@expected_fibre_data[:vendor],
|
433
|
+
:modeldescription=>@expected_fibre_data[:model]
|
434
|
+
}
|
435
|
+
|
436
|
+
wwn = [0, 0, 0, 0, 170, 170, 170, 170]
|
437
|
+
hba_profile = {
|
438
|
+
:fabricname=>wwn,
|
439
|
+
:instancename=>hba_data[:instancename],
|
440
|
+
:portspeed=>8,
|
441
|
+
:nodewwn=>wwn,
|
442
|
+
:portwwn=>wwn
|
443
|
+
}
|
444
|
+
|
445
|
+
@connector.stubs(:values_at).with('SELECT InstanceName, Manufacturer, ModelDescription FROM MSFC_FCAdapterHBAAttributes', :root_wmi).returns([hba_data])
|
446
|
+
|
447
|
+
@connector.stubs(:values_at).with("SELECT Attributes, InstanceName FROM MSFC_FibrePortHBAAttributes", :root_wmi).returns([hba_profile])
|
448
|
+
|
449
|
+
@target.get_network_interfaces
|
450
|
+
|
451
|
+
assert_equal([@expected_fibre_data], @target.network_interfaces)
|
452
|
+
end
|
453
|
+
end
|
454
|
+
|
455
|
+
context 'for operating system information' do
|
456
|
+
setup do
|
457
|
+
@os_data = {
|
458
|
+
:caption=>'Microsoft(R) Windows(R) Server 2003, Standard Edition',
|
459
|
+
:csdversion=>'Service Pack 2',
|
460
|
+
:installdate=>'20130101000000.000000-000',
|
461
|
+
:othertypedescription=>'R2',
|
462
|
+
:roles=>[],
|
463
|
+
:version=>'5.2.3790'
|
464
|
+
}
|
465
|
+
|
466
|
+
product_key_binary = [164, 1, 1, 0, 3, 0, 0, 0, 53, 53, 48, 52, 49, 45, 49, 56, 54, 45, 48, 49, 51, 51, 48,
|
467
|
+
51, 53, 45, 55, 53, 55, 54, 51, 0, 151, 0, 0, 0, 88, 49, 52, 45, 50, 51, 56, 57, 54, 0, 0, 0, 0, 0, 0, 0,
|
468
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 255, 223, 75, 219, 238, 3, 102, 3, 0, 0,
|
469
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
470
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
471
|
+
0, 0, 0, 0, 0, 0, 0, 148, 135, 143, 209]
|
472
|
+
|
473
|
+
@connector.stubs(:value_at).with('SELECT Roles FROM Win32_ComputerSystem').returns(:roles=>[])
|
474
|
+
@connector.stubs(:value_at).with('SELECT Caption, CSDVersion, InstallDate, OtherTypeDescription, Version FROM Win32_OperatingSystem').returns(@os_data)
|
475
|
+
@connector.stubs(:registry_values_at).with('SOFTWARE\Microsoft\Windows NT\CurrentVersion').returns({:digitalproductid=>product_key_binary})
|
476
|
+
|
477
|
+
@expected_data = {
|
478
|
+
:date_installed=>DateTime.parse(@os_data[:installdate]),
|
479
|
+
:features=>[],
|
480
|
+
:kernel=>@os_data[:version],
|
481
|
+
:license_key=>'BBBBB-BBBBB-BBBBB-BBBBB-BBBBB',
|
482
|
+
:name=>'Microsoft Windows',
|
483
|
+
:roles=>@os_data[:roles],
|
484
|
+
:service_pack=>@os_data[:csdversion],
|
485
|
+
:version=>'Server 2003 R2 Standard'
|
486
|
+
}
|
487
|
+
end
|
488
|
+
|
489
|
+
should 'return operating system information via #get_operating_system' do
|
490
|
+
@target.get_operating_system
|
491
|
+
assert_equal(@expected_data, @target.operating_system)
|
492
|
+
end
|
493
|
+
|
494
|
+
context 'of a windows 2008 host' do
|
495
|
+
setup do
|
496
|
+
@target.extend(Profiles::Windows::Windows2008)
|
497
|
+
@features_qry = 'SELECT Name FROM Win32_ServerFeature'
|
498
|
+
@features_data = [{:name=>'File Server'}, {:name=>'Print Server'}]
|
499
|
+
@connector.stubs(:values_at).with(@features_qry).returns(@features_data)
|
500
|
+
|
501
|
+
@expected_data[:features] = @features_data.map{|h| h[:name]}
|
502
|
+
end
|
503
|
+
|
504
|
+
should 'return the enabled OS features of the OS (only for windows 2008)' do
|
505
|
+
@connector.stubs(:values_at).with(@features_qry).returns(@features_data)
|
506
|
+
@target.get_operating_system
|
507
|
+
assert_equal(@expected_data, @target.operating_system)
|
508
|
+
end
|
509
|
+
end
|
510
|
+
end
|
511
|
+
|
512
|
+
# context 'for system roles' do
|
513
|
+
# should 'return a list of system roles via #get_system_roles' do
|
514
|
+
# expected_data = [
|
515
|
+
# 'PrimaryDomainController',
|
516
|
+
# 'IIS7',
|
517
|
+
# 'OracleRDMS',
|
518
|
+
# 'TerminalServer',
|
519
|
+
# 'TerminalServicesLicenseServer'
|
520
|
+
# ]
|
521
|
+
|
522
|
+
# @connector.stubs(:value_at).with('SELECT Roles FROM Win32_ComputerSystem').returns({:roles=>['Primary_Domain_Controller']})
|
523
|
+
# @connector.stubs(:registry_values_at).with(Profiles::Windows::IIS_KEYPATH).returns({:majorversion=>7})
|
524
|
+
# oracle_key = "#{Profiles::Windows::ORACLE_KEYPATH}\\KEY_OracleHome11g"
|
525
|
+
# @connector.stubs(:registry_subkeys_at).with(Profiles::Windows::ORACLE_KEYPATH).returns([oracle_key])
|
526
|
+
# @connector.stubs(:registry_values_at).with(oracle_key).returns({:oracle_group_name=>'Oracle - Orahome11g'})
|
527
|
+
|
528
|
+
# @connector.stubs(:value_at).with('SELECT TerminalServerMode FROM Win32_TerminalServiceSetting').returns({:terminalservermode=>1})
|
529
|
+
# @connector.stubs(:value_at).with("SELECT * FROM Win32_Service WHERE Caption = 'Terminal Server Licensing'").returns(true)
|
530
|
+
|
531
|
+
# @target.get_system_roles
|
532
|
+
# end
|
533
|
+
# end
|
534
|
+
end
|
535
|
+
end
|
536
|
+
end
|