13
13
import os
14
14
import re
15
15
import sys
16
+ import signal
16
17
import uuid
17
18
import boto3
18
19
19
20
import openstack
20
21
21
-
22
+ # Globals
22
23
TESTCONTNAME = "scs-test-container"
24
+ EC2CRED = None
25
+ OSCONN = None
23
26
24
27
logger = logging .getLogger (__name__ )
25
28
mandatory_services = ["compute" , "identity" , "image" , "network" ,
28
31
29
32
30
33
def 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"
31
35
services = conn .service_catalog
32
36
37
+ # We don't require swift if S3 can be found otherwise
33
38
if s3_credentials :
34
39
mandatory_services .remove ("object-store" )
35
40
for svc in services :
@@ -113,10 +118,36 @@ def s3_from_env(creds, fieldnm, env, prefix=""):
113
118
logger .warning (f"s3_creds[{ fieldnm } ] not set" )
114
119
115
120
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
+
116
146
def 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
120
151
rgx = re .compile (r"^(https*://[^/]*)/" )
121
152
match = rgx .match (endpoint )
122
153
if match :
@@ -130,25 +161,27 @@ def s3_from_ostack(creds, conn, endpoint):
130
161
ec2_dict = eval (ec2_creds [0 ].blob , {"null" : None })
131
162
creds ["AK" ] = ec2_dict ["access" ]
132
163
creds ["SK" ] = ec2_dict ["secret" ]
133
- return None
164
+ return
134
165
# Generate keyid and secret
135
166
ak = uuid .uuid4 ().hex
136
167
sk = uuid .uuid4 ().hex
137
168
blob = f'{{"access": "{ ak } ", "secret": "{ sk } "}}'
138
169
try :
170
+ install_sighandler (conn )
139
171
crd = conn .identity .create_credential (type = "ec2" , blob = blob ,
140
172
user_id = conn .current_user_id ,
141
173
project_id = conn .current_project_id )
142
174
creds ["AK" ] = ak
143
175
creds ["SK" ] = sk
144
- return crd .id
176
+ EC2CRED = crd .id
145
177
except BaseException as excn :
146
178
logger .warning (f"ec2 creds creation failed: { excn !s} " )
147
179
# pass
148
- return None
180
+ return
149
181
150
182
151
183
def check_for_s3_and_swift (conn : openstack .connection .Connection , s3_credentials = None ):
184
+ "Check S3 presence; either from S3_ env or swift."
152
185
# If we get credentials, we assume that there is no Swift and only test s3
153
186
if s3_credentials :
154
187
try :
@@ -176,7 +209,7 @@ def check_for_s3_and_swift(conn: openstack.connection.Connection, s3_credentials
176
209
)
177
210
return 1
178
211
# 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 )
180
213
# Overrides (var names are from libs3, in case you wonder)
181
214
s3_from_env (s3_creds , "HOST" , "S3_HOSTNAME" , "https://" )
182
215
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
211
244
if s3_buckets == [TESTCONTNAME ]:
212
245
del_bucket (s3 , TESTCONTNAME )
213
246
# Clean up ec2 cred IF we created one
214
- if ec2_cred :
215
- conn .identity .delete_credential (ec2_cred )
247
+ cleanup_ec2_cred (conn )
216
248
return result
217
249
218
250
219
251
def main ():
252
+ "Main function"
220
253
parser = argparse .ArgumentParser (
221
254
description = "SCS Mandatory IaaS Service Checker" )
222
255
parser .add_argument (
0 commit comments