in bulkprovision/bulkexecute/__init__.py [0:0]
def ProvisionProducts(self):
'''
This will go through the Dynamo table from the config and provision the given product using the params from matching the incoming scparams list.
'''
# config overides SSM
sc_param_keys = self.get_config_value("scparams").split(',')
sc_productid = self.get_config_value("scproductid")
sc_paid = self.get_config_value("scpaid")
provision_threshold = self.get_config_value("provision_threshold")
if provision_threshold is None:
provision_threshold = 10
# try to get them from SSM
if sc_productid is None:
sc_productid = self.ssm_get_parameter("/bulkdeploy/productid")
if sc_paid is None:
arr = self.ssm_get_parameter("/bulkdeploy/provisioningid").split('|')
# grab the first if there are many
sc_paid = arr[0]
# get new items
new_items = self.dynamo_query_multi("status",["NEW","RETRY"])
logger.info("Found {} new items to provision".format(len(new_items)))
count = 0
errors = 0
for drow in new_items[:provision_threshold]:
# setup variables to use later
arr_params = []
guidkey = drow["guidkey"]
param_dict = drow["launchparams"]
failed = False
ppdetails = None
errordetails = None
dbstatus = "PROVISIONING"
# keep the error message if we have one
if "errordetails" in drow:
errordetails = drow["errordetails"]
try:
# Map the incoming launchparams from the dynamo entry to the launch params from our event config
for paramkey in sc_param_keys:
par_obj = { "Key":paramkey,"Value":param_dict[paramkey] }
arr_params.append(par_obj)
# provision the product and record the important parts of the response
resp = self.sc_provision_product(sc_productid, sc_paid, guidkey, arr_params)
ppdetails = {
'ProvisionedProductId':resp['RecordDetail']['ProvisionedProductId'],
'RecordId':resp['RecordDetail']['RecordId'],
'CreatedTime':str(resp['RecordDetail']['CreatedTime']),
'Status': resp['RecordDetail']['Status']
}
except ClientError as ce:
# something wrong from the API call. this is where you will see the CFn Errors
msg = ce.response['Error']['Message']
logger.error("ClientError: {}".format(msg))
if ce.response['Error']['Code'] == "InvalidParametersException" and msg == "A stack named {} already exists.".format(guidkey):
# we got a duplicate??? just fail it, no need to retry
errors += 1
dbstatus = "DUPLICATE"
else:
errordetails = ce.response['Error']
failed = True
except KeyError as ke:
msg = "PROVISION-ERROR: Keys from CSV do not match template! Could not find {}".format(ke)
logger.error(msg)
errordetails = msg
failed = True
except Exception as e:
# Something else wrong?
logger.error(e)
failed = True
else:
count += 1
# mark the status according to the outcome from above
if failed:
errors += 1
dbstatus = "PROVISION-ERROR"
#update the dynamo table
self.updateItem(guidkey,drow["status"],dbstatus, param_dict, ppdetails, errordetails)
if len(new_items) > 0:
logger.info("Provisioned {} of {} new products with {} errors using ProductID:{} PAID:{}".format(count, len(new_items), errors, sc_productid, sc_paid))
return(self.generate_return(count))