1#!/usr/local/bin/python3.5 2 3################################################################################################### 4# 5# pyral.config - config and "consts" for the Rally 'pyral' package for REST API operations 6# 7################################################################################################### 8 9__version__ = (1, 5, 2) 10 11import datetime 12import os 13import platform 14import re 15import glob 16 17################################################################################################### 18 19PROTOCOL = "https" 20SERVER = "rally1.rallydev.com" 21WEB_SERVICE = "slm/webservice/%s" 22SCHEMA_SERVICE = "slm/schema/%s" 23AUTH_ENDPOINT = "security/authorize" 24WS_API_VERSION = "v2.0" 25 26USER_NAME = "wiley@acme.com" 27PASSWORD = "G3ronim0!" 28 29START_INDEX = 1 30MAX_PAGESIZE = 500 31MAX_ITEMS = 1000000 # a million seems an eminently reasonable limit ... 32 33RALLY_REST_HEADERS = \ 34 { 35 #'X-RallyIntegrationName' : 'Python toolkit for Rally REST API', # although syntactically this is the more correct 36 'X-RallyIntegrationName' : 'Rally REST API toolkit for Python', # this matches the format of the other language toolkits 37 'X-RallyIntegrationVendor' : 'Broadcom / Rally', 38 'X-RallyIntegrationVersion' : '%s.%s.%s' % __version__, 39 'X-RallyIntegrationLibrary' : 'pyral-%s.%s.%s' % __version__, 40 'X-RallyIntegrationPlatform' : 'Python %s' % platform.python_version(), 41 'X-RallyIntegrationOS' : platform.platform(), 42 'User-Agent' : 'Pyral Rally WebServices Agent', 43 'Content-Type' : 'application/json', 44 'Accept-Encoding' : 'gzip' 45 } 46 47################################################################################################## 48 49def timestamp(): 50 # for now, don't worry about timezone fluff, and cut off the microseconds to become millis 51 return datetime.datetime.today().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3] 52 53################################################################################################## 54 55CONFIG_SETTING_PATT = re.compile(r'^([A-Z]+)\s*=\s*(.+)$') 56RALLY_ARG_SETTING_PATT1 = re.compile(r'^--(rally[SUPW][a-z]+)=(.+)\s*$') 57RALLY_ARG_SETTING_PATT2 = re.compile(r'^--([ASUPWasupw][a-z]+)=(.+)\s*$') 58RALLY_CONFIG_FILE_PATT = re.compile(r'^--(cfg|conf|config|rallyConfig)=(\S+)$') 59 60TRUTHY_VALUES = ['t', 'true', 'y', 'yes', '1'] 61FALSEY_VALUES = ['f', 'false', 'n', 'no', '0'] 62 63################################################################################ 64 65def rallyWorkset(args): 66 """ 67 intended to supplant rallySettings as of pyral 2.0.x 68 69 priority order of Python Rally REST API server ident, credentials, workspace/project: 70 1) command line args with --rallyServer, --rallyUser, --rallyPassword, --apikey, --workspace, --project, --ping 71 2) command line arg specifying a config file --rallyConfig=<config_file_name> 72 or --config=<config_file_name> 73 or --conf=<config_file_name> 74 or --cfg=<config_file_name> 75 3) ENV variable with location of rally-<version>.cfg --> RALLY_CONFIG 76 4) current directory with rally-<version>.cfg 77 5) RALLY_SERVER, RALLY_USER_NAME, RALLY_PASSWORD, APIKEY, RALLY_WORKSPACE, RALLY_PROJECT env VARS 78 6) SERVER, USER_NAME, PASSWORD defined in this module 79 80 start by priming the return values with #6 and work your way up the priority ladder 81 """ 82 # #6 83 # start with the defaults defined in this module 84 server_creds = [SERVER, USER_NAME, PASSWORD, "", "default", "default"] 85 86 def snarfSettings(targetFile, server_creds): 87 """ 88 read the filename and look for lines containing relevant Rally settings. 89 alter the server_creds list if there are entries in the file to do so. 90 """ 91 if not os.path.exists(targetFile): 92 cfg_suffixed = "%s.cfg" % targetFile 93 if not os.path.exists(cfg_suffixed): 94 return server_creds 95 else: 96 targetFile = cfg_suffixed 97 98 try: 99 cf = open(targetFile, 'r') 100 for line in cf: 101 mo = CONFIG_SETTING_PATT.match(line) 102 if mo: 103 item, value = mo.groups() 104 if item == 'SERVER': 105 server_creds[0] = value 106 elif item == 'USER': 107 server_creds[1] = value 108 elif item == 'PASSWORD': 109 server_creds[2] = value 110 elif item == "APIKEY" or item == "API_KEY": 111 server_creds[3] = value 112 elif item == 'WORKSPACE': 113 server_creds[4] = value 114 elif item == 'PROJECT': 115 server_creds[5] = value 116 cf.close() 117 sc = "%s, %s, %s, %s, %s, %s" % tuple(server_creds) 118 return server_creds 119 except Exception as ex: 120 pass 121 122 # #5 123 # if there are environment vars, use them 124 # 125 for ix, name in enumerate(['RALLY_SERVER', 'RALLY_USER', 'RALLY_PASSWORD', 'APIKEY', 'RALLY_WORKSPACE', 'RALLY_PROJECT']): 126 if name in os.environ: 127 server_creds[ix] = os.environ[name] 128 129 # #4 130 # if there is a rally-<version>.cfg file in the current directory matching the WS_API_VERSION 131 # load with contents of that file 132 entries = glob.glob('rally-*.cfg') 133 target_version_config = 'rally-%s.cfg' % WS_API_VERSION 134 if entries: 135 if target_version_config in entries: 136 server_creds = snarfSettings(target_version_config, server_creds) 137 else: 138 print("Ignoring non-matching version of Rally config settings: %s (working version: %s)" % \ 139 (entries.pop(), WS_API_VERSION)) 140 141 # #3 142 # if there is a RALLY_CONFIG environment variable pointing to a file, load with contents of file 143 config_file = os.environ.get('RALLY_CONFIG', None) 144 if config_file: 145 server_creds = snarfSettings(config_file, server_creds) 146 147 # #2 148 # now look at the args (from command line invocation) 149 # grab any --(rallyConfig|config|conf|cfg)=<filename> args, 150 # and if filename exists attempt to load with contents therein 151 for arg in args: 152 mo = RALLY_CONFIG_FILE_PATT.match(arg) 153 if mo: 154 config_token, config_file = mo.groups() 155 server_creds = snarfSettings(config_file, server_creds) 156 157 # #1 158 # now look at the args (from command line invocation) 159 # grab any --rallyServer=?, --rallyUser=?, --rallyPassword=?, --rallyWorkspace=?, --rallyProject=? in args 160 # grab any --server=?, --user=?, --password=?, --apikey=?, --workspace=?, --project=? --ping=?in args 161 for arg in args: 162 mo = RALLY_ARG_SETTING_PATT1.match(arg) 163 if mo: 164 item, value = mo.groups() 165 if item == 'rallyServer': 166 server_creds[0] = value 167 elif item == 'rallyUser': 168 server_creds[1] = value 169 elif item == 'rallyPassword': 170 server_creds[2] = value 171 #elif item = 'rallyApikey': # enable this if we ever decide that apikey arg should ever be specified as --rallyApikey 172 # server_creds[3] = value 173 elif item == 'rallyWorkspace': 174 server_creds[4] = value 175 elif item == 'rallyProject': 176 server_creds[5] = value 177 178 mo = RALLY_ARG_SETTING_PATT2.match(arg) 179 if mo: 180 item, value = mo.groups() 181 if item == 'server': 182 server_creds[0] = value 183 elif item == 'user': 184 server_creds[1] = value 185 elif item == 'password': 186 server_creds[2] = value 187 elif item == 'apikey' or item == 'api_key': 188 server_creds[3] = value 189 elif item == 'workspace': 190 server_creds[4] = value 191 elif item == 'project': 192 server_creds[5] = value 193 194 return server_creds 195 196################################################################################ 197 198def rallySettings(args): 199 """ 200 *********** DEPRECATED ************* 201 priority order of Python Rally REST API server ident, credentials, workspace/project: 202 1) command line args with --rallyServer, --rallyUser, --rallyPassword, --workspace, --project 203 2) command line arg specifying a config file --rallyConfig=<config_file_name> 204 or --config=<config_file_name> 205 or --conf=<config_file_name> 206 or --cfg=<config_file_name> 207 3) ENV variable with location of rally-<version>.cfg --> RALLY_CONFIG 208 4) current directory with rally-<version>.cfg 209 5) RALLY_SERVER, RALLY_USER_NAME, RALLY_PASSWORD, RALLY_WORKSPACE, RALLY_PROJECT env VARS 210 6) SERVER, USER_NAME, PASSWORD defined in this module 211 212 start by priming the return values with #6 and work your way up the priority ladder 213 """ 214 # #6 215 # start with the defaults defined in this module 216 server_creds = [SERVER, USER_NAME, PASSWORD, "default", "default"] 217 218 def snarfSettings(targetFile, server_creds): 219 """ 220 read the filename and look for lines containing relevant Rally settings. 221 alter the server_creds list if there are entries in the file to do so. 222 """ 223 if not os.path.exists(targetFile): 224 cfg_suffixed = "%s.cfg" % targetFile 225 if not os.path.exists(cfg_suffixed): 226 return server_creds 227 else: 228 targetFile = cfg_suffixed 229 230 try: 231 cf = open(targetFile, 'r') 232 for line in cf: 233 mo = CONFIG_SETTING_PATT.match(line) 234 if mo: 235 item, value = mo.groups() 236 if item == 'SERVER': 237 server_creds[0] = value 238 elif item == 'USER': 239 server_creds[1] = value 240 elif item == 'PASSWORD': 241 server_creds[2] = value 242 elif item == 'WORKSPACE': 243 server_creds[3] = value 244 elif item == 'PROJECT': 245 server_creds[4] = value 246 cf.close() 247 sc = "%s, %s, %s, %s, %s" % tuple(server_creds) 248 return server_creds 249 except Exception as ex: 250 pass 251 252 # #5 253 # if there are environment vars, use them 254 # 255 for ix, name in enumerate(['RALLY_SERVER', 'RALLY_USER', 'RALLY_PASSWORD', 'RALLY_WORKSPACE', 'RALLY_PROJECT']): 256 if name in os.environ: 257 server_creds[ix] = os.environ[name] 258 259 # #4 260 # if there is a rally-<version>.cfg file in the current directory matching the WS_API_VERSION 261 # load with contents of that file 262 entries = glob.glob('rally-*.cfg') 263 target_version_config = 'rally-%s.cfg' % WS_API_VERSION 264 if entries: 265 if target_version_config in entries: 266 server_creds = snarfSettings(target_version_config, server_creds) 267 else: 268 print("Ignoring non-matching version of Rally config settings: %s (working version: %s)" % \ 269 (entries.pop(), WS_API_VERSION)) 270 271 # #3 272 # if there is a RALLY_CONFIG environment variable pointing to a file, load with contents of file 273 config_file = os.environ.get('RALLY_CONFIG', None) 274 if config_file: 275 server_creds = snarfSettings(config_file, server_creds) 276 277 # #2 278 # now look at the args (from command line invocation) 279 # grab any --(rallyConfig|config|conf|cfg)=<filename> args, 280 # and if filename exists attempt to load with contents therein 281 for arg in args: 282 mo = RALLY_CONFIG_FILE_PATT.match(arg) 283 if mo: 284 config_token, config_file = mo.groups() 285 server_creds = snarfSettings(config_file, server_creds) 286 287 # #1 288 # now look at the args (from command line invocation) 289 # grab any --rallyServer=?, --rallyUser=?, --rallyPassword=?, --rallyWorkspace=?, --rallyProject=? in args 290 # grab any --server=?, --user=?, --password=?, --workspace=?, --project=? in args 291 for arg in args: 292 mo = RALLY_ARG_SETTING_PATT1.match(arg) 293 if mo: 294 item, value = mo.groups() 295 if item == 'rallyServer': 296 server_creds[0] = value 297 elif item == 'rallyUser': 298 server_creds[1] = value 299 elif item == 'rallyPassword': 300 server_creds[2] = value 301 elif item == 'rallyWorkspace': 302 server_creds[3] = value 303 elif item == 'rallyProject': 304 server_creds[4] = value 305 306 mo = RALLY_ARG_SETTING_PATT2.match(arg) 307 if mo: 308 item, value = mo.groups() 309 if item == 'server': 310 server_creds[0] = value 311 elif item == 'user': 312 server_creds[1] = value 313 elif item == 'password': 314 server_creds[2] = value 315 elif item == 'workspace': 316 server_creds[3] = value 317 elif item == 'project': 318 server_creds[4] = value 319 320 return server_creds 321 322################################################################################################### 323################################################################################################### 324