Fixes incorrect parenthesis format & adds ft_logger import
[functest.git] / testcases / security_scan / security_scan.py
1 #!/usr/bin/python
2 #
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
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
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.
14
15 import argparse
16 import connect
17 import datetime
18 import os
19
20 from ConfigParser import SafeConfigParser
21 from keystoneclient.auth.identity import v2
22 from keystoneclient import session
23 from novaclient import client
24
25 import functest.utils.functest_logger as ft_logger
26
27 __version__ = 0.1
28 __author__ = 'Luke Hinds (lhinds@redhat.com)'
29 __url__ = 'https://wiki.opnfv.org/display/functest/Functest+Security'
30
31 # Global vars
32 INSTALLER_IP = os.getenv('INSTALLER_IP')
33 oscapbin = 'sudo /bin/oscap'
34
35 # Configure Nova Credentials
36 com = 'sudo hiera admin_password'
37 connect = connect.novaManager(com)
38 keypass = connect.keystonepass()
39 auth = v2.Password(auth_url='http://{0}:5000/v2.0'.format(INSTALLER_IP),
40                    username='admin',
41                    password=str(keypass).rstrip(),
42                    tenant_name='admin')
43 sess = session.Session(auth=auth)
44 nova = client.Client(2, session=sess)
45
46
47 # args
48 parser = argparse.ArgumentParser(description='OPNFV OpenSCAP Scanner')
49 parser.add_argument('--config', action='store', dest='cfgfile',
50                     help='Config file', required=True)
51 args = parser.parse_args()
52
53 # functest logger
54 logger = ft_logger.Logger("security_scan").getLogger()
55
56 # Config Parser
57 cfgparse = SafeConfigParser()
58 cfgparse.read(args.cfgfile)
59
60
61 def run_tests(host, nodetype):
62     port = cfgparse.get(nodetype, 'port')
63     user = cfgparse.get(nodetype, 'user')
64     user_key = cfgparse.get(nodetype, 'user_key')
65     logger.info("Host: {0} Selected Profile: {1}").format(host, nodetype)
66     logger.info("Creating temp file structure..")
67     createfiles(host, port, user, user_key)
68     logger.info("Installing OpenSCAP...")
69     install_pkg(host, port, user, user_key)
70     logger.info("Running scan...")
71     run_scanner(host, port, user, user_key, nodetype)
72     clean = cfgparse.get(nodetype, 'clean')
73     logger.info("Post installation tasks....")
74     post_tasks(host, port, user, user_key, nodetype)
75     if clean:
76         logger.info("Cleaning down environment....")
77         logger.info("Removing OpenSCAP....")
78         removepkg(host, port, user, user_key, nodetype)
79         logger.info("Deleting tmp file and reports (remote)...")
80         cleandir(host, port, user, user_key, nodetype)
81
82
83 def nova_iterate():
84     # Find compute nodes, active with network on ctlplane
85     for server in nova.servers.list():
86         if server.status == 'ACTIVE' and 'compute' in server.name:
87             networks = server.networks
88             nodetype = 'compute'
89             for host in networks['ctlplane']:
90                 run_tests(host, nodetype)
91         # Find controller nodes, active with network on ctlplane
92         elif server.status == 'ACTIVE' and 'controller' in server.name:
93             networks = server.networks
94             nodetype = 'controller'
95             for host in networks['ctlplane']:
96                 run_tests(host, nodetype)
97
98
99 def createfiles(host, port, user, user_key):
100     import connect
101     global tmpdir
102     localpath = os.getcwd() + '/scripts/createfiles.py'
103     remotepath = '/tmp/createfiles.py'
104     com = 'python /tmp/createfiles.py'
105     connect = connect.connectionManager(host, port, user, user_key,
106                                         localpath, remotepath, com)
107     tmpdir = connect.remotescript()
108
109
110 def install_pkg(host, port, user, user_key):
111     import connect
112     com = 'sudo yum -y install openscap-scanner scap-security-guide'
113     connect = connect.connectionManager(host, port, user, user_key, com)
114     connect.remotecmd()
115
116
117 def run_scanner(host, port, user, user_key, nodetype):
118     import connect
119     scantype = cfgparse.get(nodetype, 'scantype')
120     profile = cfgparse.get(nodetype, 'profile')
121     results = cfgparse.get(nodetype, 'results')
122     report = cfgparse.get(nodetype, 'report')
123     secpolicy = cfgparse.get(nodetype, 'secpolicy')
124     # Here is where we contruct the actual scan command
125     if scantype == 'xccdf':
126         cpe = cfgparse.get(nodetype, 'cpe')
127         com = '{0} xccdf eval --profile {1} --results {2}/{3}' \
128               ' --report {2}/{4} --cpe {5} {6}'.format(oscapbin,
129                                                        profile,
130                                                        tmpdir.rstrip(),
131                                                        results,
132                                                        report,
133                                                        cpe,
134                                                        secpolicy)
135         connect = connect.connectionManager(host, port, user, user_key, com)
136         connect.remotecmd()
137     elif scantype == 'oval':
138         com = '{0} oval eval --results {1}/{2} '
139         '--report {1}/{3} {4}'.format(oscapbin, tmpdir.rstrip(),
140                                       results, report, secpolicy)
141         connect = connect.connectionManager(host, port, user, user_key, com)
142         connect.remotecmd()
143     else:
144         com = '{0} oval-collect '.format(oscapbin)
145         connect = connect.connectionManager(host, port, user, user_key, com)
146         connect.remotecmd()
147
148
149 def post_tasks(host, port, user, user_key, nodetype):
150     import connect
151     # Create the download folder for functest dashboard and download reports
152     reports_dir = cfgparse.get(nodetype, 'reports_dir')
153     dl_folder = os.path.join(reports_dir, host + "_" +
154                              datetime.datetime.
155                              now().strftime('%Y-%m-%d_%H-%M-%S'))
156     os.makesdir(dl_folder, 0755)
157     report = cfgparse.get(nodetype, 'report')
158     results = cfgparse.get(nodetype, 'results')
159     reportfile = '{0}/{1}'.format(tmpdir.rstrip(), report)
160     connect = connect.connectionManager(host, port, user, user_key, dl_folder,
161                                         reportfile, report, results)
162     connect.download_reports()
163
164
165 def removepkg(host, port, user, user_key, nodetype):
166     import connect
167     com = 'sudo yum -y remove openscap-scanner scap-security-guide'
168     connect = connect.connectionManager(host, port, user, user_key, com)
169     connect.remotecmd()
170
171
172 def cleandir(host, port, user, user_key, nodetype):
173     import connect
174     com = 'sudo rm -r {0}'.format(tmpdir.rstrip())
175     connect = connect.connectionManager(host, port, user, user_key, com)
176     connect.remotecmd()
177
178
179 if __name__ == '__main__':
180     nova_iterate()