linux_admin 0.20.2 → 1.0.0
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/lib/linux_admin/disk.rb +75 -83
- data/lib/linux_admin/network_interface.rb +5 -5
- data/lib/linux_admin/network_interface/network_interface_rh.rb +14 -8
- data/lib/linux_admin/scap.rb +28 -43
- data/lib/linux_admin/version.rb +1 -1
- data/spec/network_interface/network_interface_rh_spec.rb +4 -1
- data/spec/network_interface_spec.rb +30 -33
- data/spec/scap_spec.rb +13 -26
- metadata +3 -9
- data/spec/data/scap/ssg-rhel6-xccdf.xml +0 -0
- data/spec/data/scap/ssg-rhel7-oval.xml +0 -0
- data/spec/data/scap/ssg-rhel7-xccdf.xml +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 37ae200177745a8eee67b4ef34405212de3de4b7
|
|
4
|
+
data.tar.gz: 34608da2633afe87941edc70e9e91d8b7b443f1c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0ce7cc837a7056db8ee5c2c5c82f64e61fb590c9bbeeaa10120f6477ece877a46ccc8f7f718961573ad391f53a88fc0942b3d2335b22807a7aa5f763140b44e2
|
|
7
|
+
data.tar.gz: 1feb8d22f59567560c974958188f668b6fda4ee352b08c7a4dc84aff96b146e0b24411e09d1de32fc1382ee5becdf1bd81fa58ee68d7a93e4b28acf536a4c786
|
data/lib/linux_admin/disk.rb
CHANGED
|
@@ -8,49 +8,6 @@ module LinuxAdmin
|
|
|
8
8
|
|
|
9
9
|
attr_accessor :path
|
|
10
10
|
|
|
11
|
-
private
|
|
12
|
-
|
|
13
|
-
def str_to_bytes(val, unit)
|
|
14
|
-
case unit
|
|
15
|
-
when 'K' then
|
|
16
|
-
val.to_f * 1_024 # 1.kilobytes
|
|
17
|
-
when 'M' then
|
|
18
|
-
val.to_f * 1_048_576 # 1.megabyte
|
|
19
|
-
when 'G' then
|
|
20
|
-
val.to_f * 1_073_741_824 # 1.gigabytes
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def overlapping_ranges?(ranges)
|
|
25
|
-
ranges.find do |range1|
|
|
26
|
-
ranges.any? do |range2|
|
|
27
|
-
range1 != range2 &&
|
|
28
|
-
ranges_overlap?(range1, range2)
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def ranges_overlap?(range1, range2) # copied from activesupport Range#overlaps?
|
|
34
|
-
range1.cover?(range2.first) || range2.cover?(range1.first)
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def check_if_partitions_overlap(partitions)
|
|
38
|
-
ranges =
|
|
39
|
-
partitions.collect do |partition|
|
|
40
|
-
start = partition[:start]
|
|
41
|
-
finish = partition[:end]
|
|
42
|
-
start.delete('%')
|
|
43
|
-
finish.delete('%')
|
|
44
|
-
start.to_f..finish.to_f
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
if overlapping_ranges?(ranges)
|
|
48
|
-
raise ArgumentError, "overlapping partitions"
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
public
|
|
53
|
-
|
|
54
11
|
def self.local
|
|
55
12
|
Dir.glob(['/dev/[vhs]d[a-z]', '/dev/xvd[a-z]']).collect do |d|
|
|
56
13
|
Disk.new :path => d
|
|
@@ -82,46 +39,6 @@ module LinuxAdmin
|
|
|
82
39
|
}
|
|
83
40
|
end
|
|
84
41
|
|
|
85
|
-
private
|
|
86
|
-
|
|
87
|
-
def parted_output
|
|
88
|
-
# TODO: Should this really catch non-zero RC, set output to the default "" and silently return [] ?
|
|
89
|
-
# If so, should other calls to parted also do the same?
|
|
90
|
-
# requires sudo
|
|
91
|
-
out = Common.run(Common.cmd(:parted),
|
|
92
|
-
:params => { nil => parted_options_array('print') }).output
|
|
93
|
-
split = []
|
|
94
|
-
out.each_line do |l|
|
|
95
|
-
if l =~ /^ [0-9].*/
|
|
96
|
-
split << l.split
|
|
97
|
-
end
|
|
98
|
-
end
|
|
99
|
-
split
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
def partition_from_parted(output_disk)
|
|
104
|
-
args = {:disk => self}
|
|
105
|
-
PARTED_FIELDS.each_index do |i|
|
|
106
|
-
val = output_disk[i]
|
|
107
|
-
case PARTED_FIELDS[i]
|
|
108
|
-
when :start_sector, :end_sector, :size
|
|
109
|
-
if val =~ /([0-9\.]*)([KMG])B/
|
|
110
|
-
val = str_to_bytes($1, $2)
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
when :id
|
|
114
|
-
val = val.to_i
|
|
115
|
-
|
|
116
|
-
end
|
|
117
|
-
args[PARTED_FIELDS[i]] = val
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
Partition.new(args)
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
public
|
|
124
|
-
|
|
125
42
|
def create_partition_table(type = "msdos")
|
|
126
43
|
Common.run!(Common.cmd(:parted), :params => {nil => parted_options_array("mklabel", type)})
|
|
127
44
|
end
|
|
@@ -185,6 +102,81 @@ module LinuxAdmin
|
|
|
185
102
|
|
|
186
103
|
private
|
|
187
104
|
|
|
105
|
+
def str_to_bytes(val, unit)
|
|
106
|
+
case unit
|
|
107
|
+
when 'K' then
|
|
108
|
+
val.to_f * 1_024 # 1.kilobytes
|
|
109
|
+
when 'M' then
|
|
110
|
+
val.to_f * 1_048_576 # 1.megabyte
|
|
111
|
+
when 'G' then
|
|
112
|
+
val.to_f * 1_073_741_824 # 1.gigabytes
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def overlapping_ranges?(ranges)
|
|
117
|
+
ranges.find do |range1|
|
|
118
|
+
ranges.any? do |range2|
|
|
119
|
+
range1 != range2 &&
|
|
120
|
+
ranges_overlap?(range1, range2)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def ranges_overlap?(range1, range2) # copied from activesupport Range#overlaps?
|
|
126
|
+
range1.cover?(range2.first) || range2.cover?(range1.first)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def check_if_partitions_overlap(partitions)
|
|
130
|
+
ranges =
|
|
131
|
+
partitions.collect do |partition|
|
|
132
|
+
start = partition[:start]
|
|
133
|
+
finish = partition[:end]
|
|
134
|
+
start.delete('%')
|
|
135
|
+
finish.delete('%')
|
|
136
|
+
start.to_f..finish.to_f
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
if overlapping_ranges?(ranges)
|
|
140
|
+
raise ArgumentError, "overlapping partitions"
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def parted_output
|
|
145
|
+
# TODO: Should this really catch non-zero RC, set output to the default "" and silently return [] ?
|
|
146
|
+
# If so, should other calls to parted also do the same?
|
|
147
|
+
# requires sudo
|
|
148
|
+
out = Common.run(Common.cmd(:parted),
|
|
149
|
+
:params => { nil => parted_options_array('print') }).output
|
|
150
|
+
split = []
|
|
151
|
+
out.each_line do |l|
|
|
152
|
+
if l =~ /^ [0-9].*/
|
|
153
|
+
split << l.split
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
split
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def partition_from_parted(output_disk)
|
|
161
|
+
args = {:disk => self}
|
|
162
|
+
PARTED_FIELDS.each_index do |i|
|
|
163
|
+
val = output_disk[i]
|
|
164
|
+
case PARTED_FIELDS[i]
|
|
165
|
+
when :start_sector, :end_sector, :size
|
|
166
|
+
if val =~ /([0-9\.]*)([KMG])B/
|
|
167
|
+
val = str_to_bytes($1, $2)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
when :id
|
|
171
|
+
val = val.to_i
|
|
172
|
+
|
|
173
|
+
end
|
|
174
|
+
args[PARTED_FIELDS[i]] = val
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
Partition.new(args)
|
|
178
|
+
end
|
|
179
|
+
|
|
188
180
|
def parted_options_array(*args)
|
|
189
181
|
args = args.first if args.first.kind_of?(Array)
|
|
190
182
|
parted_default_options + args
|
|
@@ -23,15 +23,12 @@ module LinuxAdmin
|
|
|
23
23
|
# Creates an instance of the correct NetworkInterface subclass for the local distro
|
|
24
24
|
def self.new(*args)
|
|
25
25
|
self == LinuxAdmin::NetworkInterface ? dist_class.new(*args) : super
|
|
26
|
-
rescue MissingConfigurationFileError
|
|
27
|
-
NetworkInterfaceGeneric.new(*args)
|
|
28
26
|
end
|
|
29
27
|
|
|
30
28
|
# @return [String] the interface for networking operations
|
|
31
29
|
attr_reader :interface
|
|
32
30
|
|
|
33
31
|
# @param interface [String] Name of the network interface to manage
|
|
34
|
-
# @raise [NetworkInterfaceError] if network information cannot be retrieved
|
|
35
32
|
def initialize(interface)
|
|
36
33
|
@interface = interface
|
|
37
34
|
reload
|
|
@@ -40,10 +37,13 @@ module LinuxAdmin
|
|
|
40
37
|
# Gathers current network information for this interface
|
|
41
38
|
#
|
|
42
39
|
# @return [Boolean] true if network information was gathered successfully
|
|
43
|
-
# @raise [NetworkInterfaceError] if network information cannot be retrieved
|
|
44
40
|
def reload
|
|
45
41
|
@network_conf = {}
|
|
46
|
-
|
|
42
|
+
begin
|
|
43
|
+
ip_output = ip_show
|
|
44
|
+
rescue NetworkInterfaceError
|
|
45
|
+
return false
|
|
46
|
+
end
|
|
47
47
|
|
|
48
48
|
parse_ip4(ip_output)
|
|
49
49
|
parse_ip6(ip_output, :global)
|
|
@@ -10,8 +10,7 @@ module LinuxAdmin
|
|
|
10
10
|
|
|
11
11
|
# @param interface [String] Name of the network interface to manage
|
|
12
12
|
def initialize(interface)
|
|
13
|
-
@interface_file =
|
|
14
|
-
raise MissingConfigurationFileError unless File.exist?(@interface_file)
|
|
13
|
+
@interface_file = self.class.path_to_interface_config_file(interface)
|
|
15
14
|
super
|
|
16
15
|
parse_conf
|
|
17
16
|
end
|
|
@@ -20,12 +19,15 @@ module LinuxAdmin
|
|
|
20
19
|
def parse_conf
|
|
21
20
|
@interface_config = {}
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
if @interface_file.file?
|
|
23
|
+
File.foreach(@interface_file) do |line|
|
|
24
|
+
next if line =~ /^\s*#/
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
key, value = line.split('=').collect(&:strip)
|
|
27
|
+
@interface_config[key] = value
|
|
28
|
+
end
|
|
28
29
|
end
|
|
30
|
+
|
|
29
31
|
@interface_config["NM_CONTROLLED"] = "no"
|
|
30
32
|
end
|
|
31
33
|
|
|
@@ -159,7 +161,7 @@ module LinuxAdmin
|
|
|
159
161
|
# @return [Boolean] true if the interface was successfully brought up with the
|
|
160
162
|
# new configuration, false otherwise
|
|
161
163
|
def save
|
|
162
|
-
old_contents = File.read(@interface_file)
|
|
164
|
+
old_contents = @interface_file.file? ? File.read(@interface_file) : ""
|
|
163
165
|
|
|
164
166
|
stop_success = stop
|
|
165
167
|
# Stop twice because when configure both ipv4 and ipv6 as dhcp, ipv6 dhcp client will
|
|
@@ -178,7 +180,11 @@ module LinuxAdmin
|
|
|
178
180
|
return false
|
|
179
181
|
end
|
|
180
182
|
|
|
181
|
-
|
|
183
|
+
reload
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def self.path_to_interface_config_file(interface)
|
|
187
|
+
Pathname.new(IFACE_DIR).join("ifcfg-#{interface}")
|
|
182
188
|
end
|
|
183
189
|
|
|
184
190
|
private
|
data/lib/linux_admin/scap.rb
CHANGED
|
@@ -2,9 +2,11 @@ require 'nokogiri'
|
|
|
2
2
|
|
|
3
3
|
module LinuxAdmin
|
|
4
4
|
class Scap
|
|
5
|
-
PROFILE_ID = "
|
|
5
|
+
PROFILE_ID = "xccdf_org.ssgproject.content_profile_linux-admin-scap".freeze
|
|
6
6
|
SSG_XML_PATH = Pathname.new("/usr/share/xml/scap/ssg/content/")
|
|
7
7
|
|
|
8
|
+
attr_reader :platform
|
|
9
|
+
|
|
8
10
|
def self.openscap_available?
|
|
9
11
|
require 'openscap'
|
|
10
12
|
true
|
|
@@ -12,28 +14,36 @@ module LinuxAdmin
|
|
|
12
14
|
false
|
|
13
15
|
end
|
|
14
16
|
|
|
15
|
-
def self.ssg_available?
|
|
16
|
-
|
|
17
|
+
def self.ssg_available?(platform)
|
|
18
|
+
ds_file(platform).exist?
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.ds_file(platform)
|
|
22
|
+
SSG_XML_PATH.join("ssg-#{platform}-ds.xml")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def initialize(platform)
|
|
26
|
+
@platform = platform
|
|
17
27
|
end
|
|
18
28
|
|
|
19
29
|
def lockdown(*args)
|
|
20
30
|
raise "OpenSCAP not available" unless self.class.openscap_available?
|
|
21
|
-
raise "SCAP Security Guide not available" unless self.class.ssg_available?
|
|
31
|
+
raise "SCAP Security Guide not available" unless self.class.ssg_available?(platform)
|
|
22
32
|
|
|
23
33
|
values = args.last.kind_of?(Hash) ? args.pop : {}
|
|
24
34
|
rules = args
|
|
25
35
|
|
|
26
36
|
raise "No SCAP rules provided" if rules.empty?
|
|
27
37
|
|
|
28
|
-
|
|
29
|
-
lockdown_profile(
|
|
38
|
+
with_ds_file(rules, values) do |path|
|
|
39
|
+
lockdown_profile(path, PROFILE_ID)
|
|
30
40
|
end
|
|
31
41
|
end
|
|
32
42
|
|
|
33
|
-
def lockdown_profile(
|
|
43
|
+
def lockdown_profile(ds_path, profile_id)
|
|
34
44
|
raise "OpenSCAP not available" unless self.class.openscap_available?
|
|
35
45
|
|
|
36
|
-
session = OpenSCAP::Xccdf::Session.new(
|
|
46
|
+
session = OpenSCAP::Xccdf::Session.new(ds_path)
|
|
37
47
|
session.load
|
|
38
48
|
session.profile = profile_id
|
|
39
49
|
session.evaluate
|
|
@@ -44,40 +54,12 @@ module LinuxAdmin
|
|
|
44
54
|
|
|
45
55
|
private
|
|
46
56
|
|
|
47
|
-
def
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
def self.oval_file
|
|
52
|
-
local_ssg_file("oval")
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def self.local_ssg_file(type)
|
|
56
|
-
Dir.glob(SSG_XML_PATH.join("ssg-*-#{type}.xml")).detect { |f| f =~ /ssg-\w+-#{type}.xml/ }
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def tempdir
|
|
60
|
-
@tempdir ||= Pathname.new(Dir.tmpdir)
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def xccdf_file
|
|
64
|
-
@xccdf_file ||= self.class.xccdf_file
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def oval_file
|
|
68
|
-
@oval_file ||= self.class.oval_file
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def with_xml_files(rules, values)
|
|
72
|
-
FileUtils.cp(oval_file, tempdir)
|
|
73
|
-
|
|
74
|
-
Tempfile.create("scap_xccdf") do |f|
|
|
75
|
-
write_xccdf_xml(f, profile_xml(PROFILE_ID, rules, values))
|
|
57
|
+
def with_ds_file(rules, values)
|
|
58
|
+
Tempfile.create("scap_ds") do |f|
|
|
59
|
+
write_ds_xml(f, profile_xml(PROFILE_ID, rules, values))
|
|
76
60
|
f.close
|
|
77
61
|
yield f.path
|
|
78
62
|
end
|
|
79
|
-
ensure
|
|
80
|
-
FileUtils.rm_f(tempdir.join(File.basename(oval_file)))
|
|
81
63
|
end
|
|
82
64
|
|
|
83
65
|
def profile_xml(profile_id, rules, values)
|
|
@@ -92,13 +74,16 @@ module LinuxAdmin
|
|
|
92
74
|
builder.doc.root.to_xml
|
|
93
75
|
end
|
|
94
76
|
|
|
95
|
-
def
|
|
96
|
-
File.open(
|
|
77
|
+
def write_ds_xml(io, profile_xml)
|
|
78
|
+
File.open(self.class.ds_file(platform)) do |f|
|
|
97
79
|
doc = Nokogiri::XML(f)
|
|
98
|
-
|
|
99
|
-
model.add_next_sibling("\n#{profile_xml}")
|
|
80
|
+
model_xml_element(doc).add_next_sibling("\n#{profile_xml}")
|
|
100
81
|
io.write(doc.root.to_xml)
|
|
101
82
|
end
|
|
102
83
|
end
|
|
84
|
+
|
|
85
|
+
def model_xml_element(doc)
|
|
86
|
+
doc.css("//nist_list|model", "nist_list" => "http://checklists.nist.gov/xccdf/1.2").detect { |model| model.namespace.prefix.nil? }
|
|
87
|
+
end
|
|
103
88
|
end
|
|
104
89
|
end
|
data/lib/linux_admin/version.rb
CHANGED
|
@@ -39,8 +39,11 @@ EOF
|
|
|
39
39
|
|
|
40
40
|
subject(:dhcp_interface) do
|
|
41
41
|
allow(File).to receive(:exist?).and_return(true)
|
|
42
|
+
stub_path = described_class.path_to_interface_config_file(device_name)
|
|
43
|
+
allow(Pathname).to receive(:new).and_return(stub_path)
|
|
44
|
+
allow(stub_path).to receive(:file?).and_return(true)
|
|
42
45
|
stub_foreach_to_string(ifcfg_file_dhcp)
|
|
43
|
-
allow(AwesomeSpawn).to receive(:run!).exactly(
|
|
46
|
+
allow(AwesomeSpawn).to receive(:run!).exactly(6).times.and_return(result("", 0))
|
|
44
47
|
described_class.new(device_name)
|
|
45
48
|
end
|
|
46
49
|
|
|
@@ -1,22 +1,7 @@
|
|
|
1
1
|
describe LinuxAdmin::NetworkInterface do
|
|
2
|
+
let(:device_name) { "eth0" }
|
|
3
|
+
let(:config_file_path) { LinuxAdmin::NetworkInterfaceRH.path_to_interface_config_file(device_name) }
|
|
2
4
|
context "on redhat systems" do
|
|
3
|
-
subject(:subj_success) do
|
|
4
|
-
allow_any_instance_of(described_class).to receive(:ip_show).and_return(nil)
|
|
5
|
-
allow(LinuxAdmin::Distros).to receive(:local).and_return(LinuxAdmin::Distros.rhel)
|
|
6
|
-
described_class.dist_class(true)
|
|
7
|
-
allow(File).to receive(:exist?).and_return(true)
|
|
8
|
-
allow(File).to receive(:foreach).and_return("")
|
|
9
|
-
described_class.new("eth0")
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
subject(:subj_failure) do
|
|
13
|
-
allow_any_instance_of(described_class).to receive(:ip_show).and_return(nil)
|
|
14
|
-
allow(LinuxAdmin::Distros).to receive(:local).and_return(LinuxAdmin::Distros.rhel)
|
|
15
|
-
described_class.dist_class(true)
|
|
16
|
-
allow(File).to receive(:exist?).and_return(false)
|
|
17
|
-
described_class.new("eth0")
|
|
18
|
-
end
|
|
19
|
-
|
|
20
5
|
describe ".dist_class" do
|
|
21
6
|
it "returns NetworkInterfaceRH" do
|
|
22
7
|
allow(LinuxAdmin::Distros).to receive(:local).and_return(LinuxAdmin::Distros.rhel)
|
|
@@ -25,24 +10,29 @@ describe LinuxAdmin::NetworkInterface do
|
|
|
25
10
|
end
|
|
26
11
|
|
|
27
12
|
describe ".new" do
|
|
28
|
-
|
|
29
|
-
|
|
13
|
+
before do
|
|
14
|
+
allow_any_instance_of(described_class).to receive(:ip_show).and_raise(LinuxAdmin::NetworkInterfaceError.new(nil, nil))
|
|
15
|
+
allow(LinuxAdmin::Distros).to receive(:local).and_return(LinuxAdmin::Distros.rhel)
|
|
16
|
+
described_class.dist_class(true)
|
|
17
|
+
allow(Pathname).to receive(:new).and_return(config_file_path)
|
|
30
18
|
end
|
|
31
19
|
|
|
32
|
-
it "creates a
|
|
33
|
-
expect(
|
|
20
|
+
it "creates a NetworkInterfaceRH instance if the config file does exist" do
|
|
21
|
+
expect(config_file_path).to receive(:file?).and_return(true)
|
|
22
|
+
expect(File).to receive(:foreach).and_return("")
|
|
23
|
+
|
|
24
|
+
expect(described_class.new(device_name)).to be_an_instance_of(LinuxAdmin::NetworkInterfaceRH)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "creates a NetworkInterfaceRH instance if the config file does not exist" do
|
|
28
|
+
expect(config_file_path).to receive(:file?).and_return(false)
|
|
29
|
+
|
|
30
|
+
expect(described_class.new(device_name)).to be_an_instance_of(LinuxAdmin::NetworkInterfaceRH)
|
|
34
31
|
end
|
|
35
32
|
end
|
|
36
33
|
end
|
|
37
34
|
|
|
38
35
|
context "on other linux systems" do
|
|
39
|
-
subject do
|
|
40
|
-
allow_any_instance_of(described_class).to receive(:ip_show).and_return(nil)
|
|
41
|
-
allow(LinuxAdmin::Distros).to receive(:local).and_return(LinuxAdmin::Distros.generic)
|
|
42
|
-
described_class.dist_class(true)
|
|
43
|
-
described_class.new("eth0")
|
|
44
|
-
end
|
|
45
|
-
|
|
46
36
|
describe ".dist_class" do
|
|
47
37
|
it "returns NetworkInterfaceGeneric" do
|
|
48
38
|
allow(LinuxAdmin::Distros).to receive(:local).and_return(LinuxAdmin::Distros.generic)
|
|
@@ -51,6 +41,13 @@ describe LinuxAdmin::NetworkInterface do
|
|
|
51
41
|
end
|
|
52
42
|
|
|
53
43
|
describe ".new" do
|
|
44
|
+
subject do
|
|
45
|
+
allow_any_instance_of(described_class).to receive(:ip_show).and_raise(LinuxAdmin::NetworkInterfaceError.new(nil, nil))
|
|
46
|
+
allow(LinuxAdmin::Distros).to receive(:local).and_return(LinuxAdmin::Distros.generic)
|
|
47
|
+
described_class.dist_class(true)
|
|
48
|
+
described_class.new(device_name)
|
|
49
|
+
end
|
|
50
|
+
|
|
54
51
|
it "creates a NetworkInterfaceGeneric instance" do
|
|
55
52
|
expect(subject).to be_an_instance_of(LinuxAdmin::NetworkInterfaceGeneric)
|
|
56
53
|
end
|
|
@@ -125,7 +122,7 @@ IP_OUT
|
|
|
125
122
|
allow(AwesomeSpawn).to receive(:run!).with(*IP_SHOW_ARGS).and_return(result(IP_ADDR_OUT, 0))
|
|
126
123
|
allow(AwesomeSpawn).to receive(:run!).with(*IP_ROUTE_ARGS).and_return(result(IP_ROUTE_OUT, 0))
|
|
127
124
|
allow(AwesomeSpawn).to receive(:run!).with(*IP6_ROUTE_ARGS).and_return(result(IP6_ROUTE_OUT, 0))
|
|
128
|
-
described_class.new(
|
|
125
|
+
described_class.new(device_name)
|
|
129
126
|
end
|
|
130
127
|
|
|
131
128
|
subject(:subj6) do
|
|
@@ -135,7 +132,7 @@ IP_OUT
|
|
|
135
132
|
allow(AwesomeSpawn).to receive(:run!).with(*IP_SHOW_ARGS).and_return(result(IP6_ADDR_OUT, 0))
|
|
136
133
|
allow(AwesomeSpawn).to receive(:run!).with(*IP_ROUTE_ARGS).and_return(result(IP_ROUTE_OUT, 0))
|
|
137
134
|
allow(AwesomeSpawn).to receive(:run!).with(*IP6_ROUTE_ARGS).and_return(result(IP6_ROUTE_OUT, 0))
|
|
138
|
-
described_class.new(
|
|
135
|
+
described_class.new(device_name)
|
|
139
136
|
end
|
|
140
137
|
|
|
141
138
|
subject(:subj_no_net) do
|
|
@@ -145,7 +142,7 @@ IP_OUT
|
|
|
145
142
|
allow(AwesomeSpawn).to receive(:run!).with(*IP_SHOW_ARGS).and_return(result(IP_NONE_ADDR_OUT, 0))
|
|
146
143
|
allow(AwesomeSpawn).to receive(:run!).with(*IP_ROUTE_ARGS).and_return(result(IP_ROUTE_OUT, 0))
|
|
147
144
|
allow(AwesomeSpawn).to receive(:run!).with(*IP6_ROUTE_ARGS).and_return(result(IP6_ROUTE_OUT, 0))
|
|
148
|
-
described_class.new(
|
|
145
|
+
described_class.new(device_name)
|
|
149
146
|
end
|
|
150
147
|
|
|
151
148
|
def result(output, exit_status)
|
|
@@ -153,11 +150,11 @@ IP_OUT
|
|
|
153
150
|
end
|
|
154
151
|
|
|
155
152
|
describe "#reload" do
|
|
156
|
-
it "
|
|
153
|
+
it "returns false when ip addr show fails" do
|
|
157
154
|
subj
|
|
158
155
|
awesome_error = AwesomeSpawn::CommandResultError.new("", nil)
|
|
159
156
|
allow(AwesomeSpawn).to receive(:run!).with(*IP_SHOW_ARGS).and_raise(awesome_error)
|
|
160
|
-
expect
|
|
157
|
+
expect(subj.reload).to eq(false)
|
|
161
158
|
end
|
|
162
159
|
|
|
163
160
|
it "raises when ip route fails" do
|
data/spec/scap_spec.rb
CHANGED
|
@@ -1,61 +1,48 @@
|
|
|
1
1
|
describe LinuxAdmin::Scap do
|
|
2
|
+
subject { described_class.new("rhel7") }
|
|
3
|
+
|
|
2
4
|
describe "#lockdown" do
|
|
3
5
|
it "raises if given no rules" do
|
|
4
|
-
stub_const("LinuxAdmin::Scap::SSG_XML_PATH", Pathname.new(data_file_path("scap")))
|
|
5
|
-
scap = described_class.new
|
|
6
6
|
allow(described_class).to receive(:openscap_available?).and_return(true)
|
|
7
7
|
allow(described_class).to receive(:ssg_available?).and_return(true)
|
|
8
|
-
|
|
9
|
-
expect {
|
|
8
|
+
|
|
9
|
+
expect { subject.lockdown("value1" => true) }.to raise_error(RuntimeError)
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
describe "#profile_xml (private)" do
|
|
14
14
|
it "creates a Profile tag" do
|
|
15
|
-
profile_xml =
|
|
15
|
+
profile_xml = subject.send(:profile_xml, "test-profile", [], {})
|
|
16
16
|
expect(profile_xml).to match(%r{<Profile id="test-profile">.*</Profile>}m)
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
it "creates a title tag" do
|
|
20
|
-
profile_xml =
|
|
20
|
+
profile_xml = subject.send(:profile_xml, "test-profile", [], {})
|
|
21
21
|
expect(profile_xml).to match(%r{<title>test-profile</title>}m)
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
it "creates a description tag" do
|
|
25
|
-
profile_xml =
|
|
25
|
+
profile_xml = subject.send(:profile_xml, "test-profile", [], {})
|
|
26
26
|
expect(profile_xml).to match(%r{<description>test-profile</description>}m)
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
it "creates a select tag for each rule" do
|
|
30
|
-
profile_xml =
|
|
30
|
+
profile_xml = subject.send(:profile_xml, "test-profile", %w(rule1 rule2), {})
|
|
31
31
|
expect(profile_xml).to match(%r{<select idref="rule1" selected="true"/>}m)
|
|
32
32
|
expect(profile_xml).to match(%r{<select idref="rule2" selected="true"/>}m)
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
it "creates a refine-value tag for each value" do
|
|
36
|
-
profile_xml =
|
|
36
|
+
profile_xml = subject.send(:profile_xml, "test-profile", [], "key1" => "val1", "key2" => "val2")
|
|
37
37
|
expect(profile_xml).to match(%r{<refine-value idref="key1" selector="val1"/>}m)
|
|
38
38
|
expect(profile_xml).to match(%r{<refine-value idref="key2" selector="val2"/>}m)
|
|
39
39
|
end
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
-
describe ".
|
|
43
|
-
it "returns
|
|
44
|
-
|
|
45
|
-
file
|
|
46
|
-
expect(file).to be_nil
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
it "returns a file if there are multiple matches" do
|
|
50
|
-
stub_const("LinuxAdmin::Scap::SSG_XML_PATH", Pathname.new(data_file_path("scap")))
|
|
51
|
-
file = described_class.send(:local_ssg_file, "xccdf")
|
|
52
|
-
expect(file).to match(%r{.*/ssg-\w+-xccdf\.xml})
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
it "returns a matching file" do
|
|
56
|
-
stub_const("LinuxAdmin::Scap::SSG_XML_PATH", Pathname.new(data_file_path("scap")))
|
|
57
|
-
file = described_class.send(:local_ssg_file, "oval")
|
|
58
|
-
expect(file).to eq("#{data_file_path("scap")}/ssg-rhel7-oval.xml")
|
|
42
|
+
describe ".ds_file" do
|
|
43
|
+
it "returns the platform ds file path" do
|
|
44
|
+
file = described_class.ds_file("rhel7")
|
|
45
|
+
expect(file.to_s).to eq("/usr/share/xml/scap/ssg/content/ssg-rhel7-ds.xml")
|
|
59
46
|
end
|
|
60
47
|
end
|
|
61
48
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: linux_admin
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brandon Dunne
|
|
@@ -21,7 +21,7 @@ authors:
|
|
|
21
21
|
autorequire:
|
|
22
22
|
bindir: bin
|
|
23
23
|
cert_chain: []
|
|
24
|
-
date: 2017-
|
|
24
|
+
date: 2017-10-03 00:00:00.000000000 Z
|
|
25
25
|
dependencies:
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: bundler
|
|
@@ -250,9 +250,6 @@ files:
|
|
|
250
250
|
- spec/data/rhn/systemid
|
|
251
251
|
- spec/data/rhn/systemid.missing_system_id
|
|
252
252
|
- spec/data/rpm/cmd_output_for_list_installed
|
|
253
|
-
- spec/data/scap/ssg-rhel6-xccdf.xml
|
|
254
|
-
- spec/data/scap/ssg-rhel7-oval.xml
|
|
255
|
-
- spec/data/scap/ssg-rhel7-xccdf.xml
|
|
256
253
|
- spec/data/subscription_manager/output_list_all_available
|
|
257
254
|
- spec/data/subscription_manager/output_list_installed_not_subscribed
|
|
258
255
|
- spec/data/subscription_manager/output_list_installed_subscribed
|
|
@@ -313,7 +310,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
313
310
|
version: '0'
|
|
314
311
|
requirements: []
|
|
315
312
|
rubyforge_project:
|
|
316
|
-
rubygems_version: 2.
|
|
313
|
+
rubygems_version: 2.6.13
|
|
317
314
|
signing_key:
|
|
318
315
|
specification_version: 4
|
|
319
316
|
summary: LinuxAdmin is a module to simplify management of linux systems.
|
|
@@ -325,9 +322,6 @@ test_files:
|
|
|
325
322
|
- spec/data/rhn/systemid
|
|
326
323
|
- spec/data/rhn/systemid.missing_system_id
|
|
327
324
|
- spec/data/rpm/cmd_output_for_list_installed
|
|
328
|
-
- spec/data/scap/ssg-rhel6-xccdf.xml
|
|
329
|
-
- spec/data/scap/ssg-rhel7-oval.xml
|
|
330
|
-
- spec/data/scap/ssg-rhel7-xccdf.xml
|
|
331
325
|
- spec/data/subscription_manager/output_list_all_available
|
|
332
326
|
- spec/data/subscription_manager/output_list_installed_not_subscribed
|
|
333
327
|
- spec/data/subscription_manager/output_list_installed_subscribed
|
|
File without changes
|
|
File without changes
|
|
File without changes
|