3 # Copyright (c) 2016 Red Hat
4 # Luke Hinds (lhinds@redhat.com)
5 # This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # 0.1: This script installs OpenSCAP on the remote host, and scans the
12 # nominated node. Post scan a report is downloaded and if '--clean' is passed
13 # all trace of the scan is removed from the remote system.
19 from ConfigParser import SafeConfigParser
22 from keystoneclient import session
23 from keystoneclient.auth.identity import v2
24 from novaclient import client
27 import functest.utils.functest_constants as ft_constants
30 __author__ = 'Luke Hinds (lhinds@redhat.com)'
31 __url__ = 'https://wiki.opnfv.org/display/functest/Functest+Security'
34 INSTALLER_IP = ft_constants.CI_INSTALLER_IP
35 oscapbin = 'sudo /bin/oscap'
36 functest_dir = '%s/security_scan/' % ft_constants.FUNCTEST_TEST_DIR
38 # Apex Spefic var needed to query Undercloud
39 if ft_constants.OS_AUTH_URL is None:
40 connect.logger.error(" Enviroment variable OS_AUTH_URL is not set")
43 OS_AUTH_URL = ft_constants.OS_AUTH_URL
46 parser = argparse.ArgumentParser(description='OPNFV OpenSCAP Scanner')
47 parser.add_argument('--config', action='store', dest='cfgfile',
48 help='Config file', required=True)
49 args = parser.parse_args()
52 cfgparse = SafeConfigParser()
53 cfgparse.read(args.cfgfile)
56 remotekey = cfgparse.get('undercloud', 'remotekey')
57 localkey = cfgparse.get('undercloud', 'localkey')
58 setup = connect.SetUp(remotekey, localkey)
62 # Configure Nova Credentials
63 com = 'sudo /usr/bin/hiera admin_password'
64 setup = connect.SetUp(com)
65 keypass = setup.keystonepass()
66 auth = v2.Password(auth_url=OS_AUTH_URL,
68 password=str(keypass).rstrip(),
70 sess = session.Session(auth=auth)
71 nova = client.Client(2, session=sess)
74 class GlobalVariables:
78 def run_tests(host, nodetype):
79 user = cfgparse.get(nodetype, 'user')
80 port = cfgparse.get(nodetype, 'port')
81 connect.logger.info("Host: {0} Selected Profile: {1}".format(host,
83 connect.logger.info("Checking internet for package installation...")
84 if internet_check(host, nodetype):
85 connect.logger.info("Internet Connection OK.")
86 connect.logger.info("Creating temp file structure..")
87 createfiles(host, port, user, localkey)
88 connect.logger.debug("Installing OpenSCAP...")
89 install_pkg(host, port, user, localkey)
90 connect.logger.debug("Running scan...")
91 run_scanner(host, port, user, localkey, nodetype)
92 clean = cfgparse.get(nodetype, 'clean')
93 connect.logger.info("Post installation tasks....")
94 post_tasks(host, port, user, localkey, nodetype)
96 connect.logger.info("Cleaning down environment....")
97 connect.logger.debug("Removing OpenSCAP....")
98 removepkg(host, port, user, localkey, nodetype)
99 connect.logger.info("Deleting tmp file and reports (remote)...")
100 cleandir(host, port, user, localkey, nodetype)
102 connect.logger.error("Internet timeout. Moving on to next node..")
107 # Find compute nodes, active with network on ctlplane
108 for server in nova.servers.list():
109 if server.status == 'ACTIVE' and 'compute' in server.name:
110 networks = server.networks
112 for host in networks['ctlplane']:
113 run_tests(host, nodetype)
114 # Find controller nodes, active with network on ctlplane
115 elif server.status == 'ACTIVE' and 'controller' in server.name:
116 networks = server.networks
117 nodetype = 'controller'
118 for host in networks['ctlplane']:
119 run_tests(host, nodetype)
122 def internet_check(host, nodetype):
124 user = cfgparse.get(nodetype, 'user')
125 port = cfgparse.get(nodetype, 'port')
126 localpath = functest_dir + 'scripts/internet_check.py'
127 remotepath = '/tmp/internet_check.py'
128 com = 'python /tmp/internet_check.py'
129 testconnect = connect.ConnectionManager(host, port, user, localkey,
130 localpath, remotepath, com)
131 connectionresult = testconnect.remotescript()
132 if connectionresult.rstrip() == 'True':
138 def createfiles(host, port, user, localkey):
140 localpath = functest_dir + 'scripts/createfiles.py'
141 remotepath = '/tmp/createfiles.py'
142 com = 'python /tmp/createfiles.py'
143 connect = connect.ConnectionManager(host, port, user, localkey,
144 localpath, remotepath, com)
145 GlobalVariables.tmpdir = connect.remotescript()
148 def install_pkg(host, port, user, localkey):
150 com = 'sudo yum -y install openscap-scanner scap-security-guide'
151 connect = connect.ConnectionManager(host, port, user, localkey, com)
155 def run_scanner(host, port, user, localkey, nodetype):
157 scantype = cfgparse.get(nodetype, 'scantype')
158 profile = cfgparse.get(nodetype, 'profile')
159 results = cfgparse.get(nodetype, 'results')
160 report = cfgparse.get(nodetype, 'report')
161 secpolicy = cfgparse.get(nodetype, 'secpolicy')
162 # Here is where we contruct the actual scan command
163 if scantype == 'xccdf':
164 cpe = cfgparse.get(nodetype, 'cpe')
165 com = '{0} xccdf eval --profile {1} --results {2}/{3}' \
166 ' --report {2}/{4}' \
167 ' --cpe {5} {6}'.format(oscapbin,
169 GlobalVariables.tmpdir.rstrip(),
174 connect = connect.ConnectionManager(host, port, user, localkey, com)
176 elif scantype == 'oval':
177 com = '{0} oval eval --results {1}/{2} '
178 '--report {1}/{3} {4}'.format(oscapbin,
179 GlobalVariables.tmpdir.rstrip(),
180 results, report, secpolicy)
181 connect = connect.ConnectionManager(host, port, user, localkey, com)
184 com = '{0} oval-collect '.format(oscapbin)
185 connect = connect.ConnectionManager(host, port, user, localkey, com)
189 def post_tasks(host, port, user, localkey, nodetype):
191 # Create the download folder for functest dashboard and download reports
192 reports_dir = cfgparse.get(nodetype, 'reports_dir')
193 dl_folder = os.path.join(reports_dir, host + "_" +
195 now().strftime('%Y-%m-%d_%H-%M-%S'))
196 os.makedirs(dl_folder, 0755)
197 report = cfgparse.get(nodetype, 'report')
198 results = cfgparse.get(nodetype, 'results')
199 reportfile = '{0}/{1}'.format(GlobalVariables.tmpdir.rstrip(), report)
200 connect = connect.ConnectionManager(host, port, user, localkey, dl_folder,
201 reportfile, report, results)
202 connect.download_reports()
205 def removepkg(host, port, user, localkey, nodetype):
207 com = 'sudo yum -y remove openscap-scanner scap-security-guide'
208 connect = connect.ConnectionManager(host, port, user, localkey, com)
212 def cleandir(host, port, user, localkey, nodetype):
214 com = 'sudo rm -r {0}'.format(GlobalVariables.tmpdir.rstrip())
215 connect = connect.ConnectionManager(host, port, user, localkey, com)
219 if __name__ == '__main__':