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.
20 from ConfigParser import SafeConfigParser
21 from keystoneclient.auth.identity import v2
22 from keystoneclient import session
23 from novaclient import client
26 __author__ = 'Luke Hinds (lhinds@redhat.com)'
27 __url__ = 'https://wiki.opnfv.org/display/functest/Functest+Security'
30 oscapbin = 'sudo /bin/oscap'
31 INSTALLER_IP = os.getenv('INSTALLER_IP')
33 # Apex Spefic var needed to query Undercloud
34 if os.getenv('OS_AUTH_URL') is None:
35 connect.logger.error(" Enviroment variable OS_AUTH_URL is not set")
38 OS_AUTH_URL = os.getenv('OS_AUTH_URL')
41 parser = argparse.ArgumentParser(description='OPNFV OpenSCAP Scanner')
42 parser.add_argument('--config', action='store', dest='cfgfile',
43 help='Config file', required=True)
44 args = parser.parse_args()
47 cfgparse = SafeConfigParser()
48 cfgparse.read(args.cfgfile)
51 remotekey = cfgparse.get('undercloud', 'remotekey')
52 localkey = cfgparse.get('undercloud', 'localkey')
53 setup = connect.SetUp(remotekey, localkey)
57 # Configure Nova Credentials
58 com = 'sudo hiera admin_password'
59 setup = connect.SetUp(com)
60 keypass = setup.keystonepass()
61 auth = v2.Password(auth_url='http://{0}:5000/v2.0'.format(OS_AUTH_URL),
63 password=str(keypass).rstrip(),
65 sess = session.Session(auth=auth)
66 nova = client.Client(2, session=sess)
69 def run_tests(host, nodetype):
70 user = cfgparse.get(nodetype, 'user')
71 port = cfgparse.get(nodetype, 'port')
72 connect.logger.info("Host: {0} Selected Profile: {1}".format(host,
74 connect.logger.info("Creating temp file structure..")
75 createfiles(host, port, user, localkey)
76 connect.logger.info("Installing OpenSCAP...")
77 install_pkg(host, port, user, localkey)
78 connect.logger.info("Running scan...")
79 run_scanner(host, port, user, localkey, nodetype)
80 clean = cfgparse.get(nodetype, 'clean')
81 connect.logger.info("Post installation tasks....")
82 post_tasks(host, port, user, localkey, nodetype)
84 connect.logger.info("Cleaning down environment....")
85 connect.logger.info("Removing OpenSCAP....")
86 removepkg(host, port, user, localkey, nodetype)
87 connect.logger.info("Deleting tmp file and reports (remote)...")
88 cleandir(host, port, user, localkey, nodetype)
92 # Find compute nodes, active with network on ctlplane
93 for server in nova.servers.list():
94 if server.status == 'ACTIVE' and 'compute' in server.name:
95 networks = server.networks
97 for host in networks['ctlplane']:
98 run_tests(host, nodetype)
99 # Find controller nodes, active with network on ctlplane
100 elif server.status == 'ACTIVE' and 'controller' in server.name:
101 networks = server.networks
102 nodetype = 'controller'
103 for host in networks['ctlplane']:
104 run_tests(host, nodetype)
107 def createfiles(host, port, user, localkey):
110 localpath = os.getcwd() + '/scripts/createfiles.py'
111 remotepath = '/tmp/createfiles.py'
112 com = 'python /tmp/createfiles.py'
113 connect = connect.ConnectionManager(host, port, user, localkey,
114 localpath, remotepath, com)
115 tmpdir = connect.remotescript()
118 def install_pkg(host, port, user, localkey):
120 com = 'sudo yum -y install openscap-scanner scap-security-guide'
121 connect = connect.ConnectionManager(host, port, user, localkey, com)
125 def run_scanner(host, port, user, localkey, nodetype):
127 scantype = cfgparse.get(nodetype, 'scantype')
128 profile = cfgparse.get(nodetype, 'profile')
129 results = cfgparse.get(nodetype, 'results')
130 report = cfgparse.get(nodetype, 'report')
131 secpolicy = cfgparse.get(nodetype, 'secpolicy')
132 # Here is where we contruct the actual scan command
133 if scantype == 'xccdf':
134 cpe = cfgparse.get(nodetype, 'cpe')
135 com = '{0} xccdf eval --profile {1} --results {2}/{3}' \
136 ' --report {2}/{4} --cpe {5} {6}'.format(oscapbin,
143 connect = connect.ConnectionManager(host, port, user, localkey, com)
145 elif scantype == 'oval':
146 com = '{0} oval eval --results {1}/{2} '
147 '--report {1}/{3} {4}'.format(oscapbin, tmpdir.rstrip(),
148 results, report, secpolicy)
149 connect = connect.ConnectionManager(host, port, user, localkey, com)
152 com = '{0} oval-collect '.format(oscapbin)
153 connect = connect.ConnectionManager(host, port, user, localkey, com)
157 def post_tasks(host, port, user, localkey, nodetype):
159 # Create the download folder for functest dashboard and download reports
160 reports_dir = cfgparse.get(nodetype, 'reports_dir')
161 dl_folder = os.path.join(reports_dir, host + "_" +
163 now().strftime('%Y-%m-%d_%H-%M-%S'))
164 os.makedirs(dl_folder, 0755)
165 report = cfgparse.get(nodetype, 'report')
166 results = cfgparse.get(nodetype, 'results')
167 reportfile = '{0}/{1}'.format(tmpdir.rstrip(), report)
168 connect = connect.ConnectionManager(host, port, user, localkey, dl_folder,
169 reportfile, report, results)
170 connect.download_reports()
173 def removepkg(host, port, user, localkey, nodetype):
175 com = 'sudo yum -y remove openscap-scanner scap-security-guide'
176 connect = connect.ConnectionManager(host, port, user, localkey, com)
180 def cleandir(host, port, user, localkey, nodetype):
182 com = 'sudo rm -r {0}'.format(tmpdir.rstrip())
183 connect = connect.ConnectionManager(host, port, user, localkey, com)
187 if __name__ == '__main__':