1313import os
1414import re
1515import sys
16+ import signal
1617import uuid
1718import boto3
1819
1920import openstack
2021
21-
22+ # Globals
2223TESTCONTNAME = "scs-test-container"
24+ EC2CRED = None
25+ OSCONN = None
2326
2427logger = logging .getLogger (__name__ )
2528mandatory_services = ["compute" , "identity" , "image" , "network" ,
2831
2932
3033def check_presence_of_mandatory_services (conn : openstack .connection .Connection , s3_credentials = None ):
34+ "Go over list of mandatory services and ensure they are all in the catalog"
3135 services = conn .service_catalog
3236
37+ # We don't require swift if S3 can be found otherwise
3338 if s3_credentials :
3439 mandatory_services .remove ("object-store" )
3540 for svc in services :
@@ -113,10 +118,36 @@ def s3_from_env(creds, fieldnm, env, prefix=""):
113118 logger .warning (f"s3_creds[{ fieldnm } ] not set" )
114119
115120
121+ def cleanup_ec2_cred (conn ):
122+ "Remove ec2_cred if created"
123+ if conn and EC2CRED :
124+ conn .identity .delete_credential (EC2CRED )
125+
126+
127+ def breakhandler (sig , frame ):
128+ "Clean up created ec2 credential is any and reraise signal"
129+ # global OSCONN
130+ # print(f"Handle signal {signal.strsignal(sig)}: Conn {os_conn}, clean cred {ec2_cred}", file=sys.stderr)
131+ cleanup_ec2_cred (OSCONN )
132+ signal .signal (sig , signal .SIG_DFL )
133+ signal .raise_signal (sig )
134+
135+
136+ def install_sighandler (conn ):
137+ "Set OpenStack connection and install signal handler"
138+ global OSCONN
139+ OSCONN = conn
140+ signal .signal (signal .SIGINT , breakhandler )
141+ signal .signal (signal .SIGTERM , breakhandler )
142+ signal .signal (signal .SIGHUP , breakhandler )
143+ signal .signal (signal .SIGPIPE , breakhandler )
144+
145+
116146def s3_from_ostack (creds , conn , endpoint ):
117- """Set creds from openstack swift/keystone
118- Returns credential ID *if* an ec2 credential was created,
119- None otherwise."""
147+ """Fill in creds from openstack swift/keystone
148+ Sets global ec2_cred *if* an ec2 credential was created,
149+ """
150+ global EC2CRED
120151 rgx = re .compile (r"^(https*://[^/]*)/" )
121152 match = rgx .match (endpoint )
122153 if match :
@@ -130,25 +161,27 @@ def s3_from_ostack(creds, conn, endpoint):
130161 ec2_dict = eval (ec2_creds [0 ].blob , {"null" : None })
131162 creds ["AK" ] = ec2_dict ["access" ]
132163 creds ["SK" ] = ec2_dict ["secret" ]
133- return None
164+ return
134165 # Generate keyid and secret
135166 ak = uuid .uuid4 ().hex
136167 sk = uuid .uuid4 ().hex
137168 blob = f'{{"access": "{ ak } ", "secret": "{ sk } "}}'
138169 try :
170+ install_sighandler (conn )
139171 crd = conn .identity .create_credential (type = "ec2" , blob = blob ,
140172 user_id = conn .current_user_id ,
141173 project_id = conn .current_project_id )
142174 creds ["AK" ] = ak
143175 creds ["SK" ] = sk
144- return crd .id
176+ EC2CRED = crd .id
145177 except BaseException as excn :
146178 logger .warning (f"ec2 creds creation failed: { excn !s} " )
147179 # pass
148- return None
180+ return
149181
150182
151183def check_for_s3_and_swift (conn : openstack .connection .Connection , s3_credentials = None ):
184+ "Check S3 presence; either from S3_ env or swift."
152185 # If we get credentials, we assume that there is no Swift and only test s3
153186 if s3_credentials :
154187 try :
@@ -176,7 +209,7 @@ def check_for_s3_and_swift(conn: openstack.connection.Connection, s3_credentials
176209 )
177210 return 1
178211 # Get S3 endpoint (swift) and ec2 creds from OpenStack (keystone)
179- ec2_cred = s3_from_ostack (s3_creds , conn , endpoint )
212+ s3_from_ostack (s3_creds , conn , endpoint )
180213 # Overrides (var names are from libs3, in case you wonder)
181214 s3_from_env (s3_creds , "HOST" , "S3_HOSTNAME" , "https://" )
182215 s3_from_env (s3_creds , "AK" , "S3_ACCESS_KEY_ID" )
@@ -211,12 +244,12 @@ def check_for_s3_and_swift(conn: openstack.connection.Connection, s3_credentials
211244 if s3_buckets == [TESTCONTNAME ]:
212245 del_bucket (s3 , TESTCONTNAME )
213246 # Clean up ec2 cred IF we created one
214- if ec2_cred :
215- conn .identity .delete_credential (ec2_cred )
247+ cleanup_ec2_cred (conn )
216248 return result
217249
218250
219251def main ():
252+ "Main function"
220253 parser = argparse .ArgumentParser (
221254 description = "SCS Mandatory IaaS Service Checker" )
222255 parser .add_argument (
0 commit comments