import os import json import boto3 import random import botocore import logging import threading import urllib3 http = urllib3.PoolManager() s3client = boto3.client('s3') logger = logging.getLogger() _region = os.environ['AWS_REGION'] s3client = boto3.client('s3', _region, config=botocore.config.Config(s3={'addressing_style':'path'})) sc_client = boto3.client('servicecatalog') polly_client = boto3.client('polly') def sendemail(toemail,fromemail,esubject,ebody): awsregion = _region charset = "UTF-8" client = boto3.client('ses',region_name=awsregion) try: response = client.send_email( Destination={ 'ToAddresses': [toemail], }, Message={ 'Body': { 'Html': { 'Charset': charset, 'Data': ebody, }, 'Text': { 'Charset': charset, 'Data': ebody, }, }, 'Subject': { 'Charset': charset, 'Data': esubject, }, }, Source=fromemail, ) except Exception as e: return( e) else: return "Email Sent to " + toemail def cfnresponse(event, context, responseStatus, responseData, physicalResourceId=None, noEcho=False): responseBody = {} responseBody['Status'] = responseStatus responseBody['Reason'] = 'See the details in CloudWatch Log Stream: ' + context.log_stream_name responseBody['PhysicalResourceId'] = physicalResourceId or context.log_stream_name responseBody['StackId'] = event['StackId'] responseBody['RequestId'] = event['RequestId'] responseBody['LogicalResourceId'] = event['LogicalResourceId'] responseBody['NoEcho'] = noEcho responseBody['Data'] = responseData json_responseBody = json.dumps(responseBody) headers = {'content-type' : '','content-length' : str(len(json_responseBody))} try: response = http.request('PUT',event['ResponseURL'],body=json_responseBody.encode('utf-8'),headers=headers) logger.debug('Status code: ' + response.reason) except Exception as e: logger.error('cfnresponse(..) failed executing requests.put(..): ' + str(e)) def timeout(event, context): logging.error('Execution is about to time out, sending failure response to CloudFormation') cfnresponse(event, context, 'FAILED',{}) def sc_listportfolio(pinfo): ret='no' portlist = sc_client.list_portfolios(AcceptLanguage='en') for port in portlist['PortfolioDetails']: mss = f"found [{port['DisplayName']}]-[{pinfo['DisplayName']}]" if port['DisplayName'] == pinfo['DisplayName']: ret='yes' print(mss) return ret def sc_create_portfolio(pinfo): _rand = random.randint(323, 24200) IdempotencyToken = "tok%s" % _rand _srand = str(_rand) pName = f"TTTT-{_srand}-{pinfo['DisplayName']}" pName = pinfo['DisplayName'] response = sc_client.create_portfolio(AcceptLanguage='en',DisplayName=pName,Description=pinfo['Description'],ProviderName=pinfo['ProviderName'],Tags=pinfo['Tags'],IdempotencyToken=IdempotencyToken) return response['PortfolioDetail']['Id'] def sc_deactivat_ver(_newversion, _prodinfo): for _product in _prodinfo: if _newversion != _product['Name']: response = sc_client.update_provisioning_artifact(AcceptLanguage='en', ProductId=_product['ProductId'], ProvisioningArtifactId=_product['ProvisioningArtifactId'], Active=False, Guidance='DEPRECATED') return 0 def sc_create_pa(ProductId, version, description, template): _rand = random.randint(323, 24200) IdempotencyToken = "tok%s" % _rand print(template + IdempotencyToken) rep = sc_client.create_provisioning_artifact(AcceptLanguage='en', ProductId=ProductId, Parameters={ 'Name': version, 'Description': description, 'Info': { "LoadTemplateFromURL": template }, 'Type': 'CLOUD_FORMATION_TEMPLATE', 'DisableTemplateValidation': True }, IdempotencyToken=IdempotencyToken ) return rep def sc_find_product(name): _ret = 'not found' try: rep = sc_client.describe_product_as_admin(AcceptLanguage='en', Name=name) _ret='found' print(rep) except Exception as e: e = str(e) print(e) if e.find('ResourceNotFoundException') > -1: print(name + ' not found') return _ret def sc_describe_product(name): rep = {} try: rep = sc_client.describe_product_as_admin( AcceptLanguage='en', Name=name) except Exception as e: e = str(e) print(e) if e.find('ResourceNotFoundException') > -1: print(name + ' not found') _ret= 'not found' return _ret ProductId = rep['ProductViewDetail']['ProductViewSummary']['ProductId'] _ret = [] for _prodversion in rep['ProvisioningArtifactSummaries']: _version = {'ProductId': ProductId, 'ProvisioningArtifactId': _prodversion[ 'Id'], 'Name': _prodversion['Name'], 'Description': _prodversion['Description']} _ret.append(_version) return _ret def mgt_ent_sc_updateProduct(_sc_productname, template): _prodinfo = sc_describe_product(_sc_productname) _versions = len(_prodinfo) + 1 ProductId = _prodinfo[0]['ProductId'] version = 'Latest %s.0' % _versions description = 'Description %s' % version pa_rep = sc_create_pa(ProductId, version, description, template) _ret = {'ProductId': ProductId, 'version': version,'ProvisioningArtifactId': pa_rep['ProvisioningArtifactDetail']['Id']} _prodinfo = sc_describe_product(_sc_productname) sc_deactivat_ver(version, _prodinfo) return _ret def sc_accoc_prod_port(pinfo): res = sc_client.associate_product_with_portfolio(AcceptLanguage='en',ProductId=pinfo['ProductId'],PortfolioId=pinfo['PortfolioId'] ) return res def sc_createproduct(pinfo): _rand = random.randint(323, 24200) _srand = str(_rand) pName = f"{pinfo['name']}" IdempotencyToken = "tok%s" % _rand myTags=[ {'Key': 'dynamokey','Value': pinfo['dykey'] }] resp = sc_client.create_product(AcceptLanguage='en',Name=pName,Owner=pinfo['owner'], Description=pinfo['description'],Distributor=pinfo['owner'], SupportDescription=pinfo['description'], SupportEmail="awssc@awssc.com", SupportUrl="https://supdportsc.com", ProductType='CLOUD_FORMATION_TEMPLATE', Tags=myTags,ProvisioningArtifactParameters={'Name': pinfo['version'], 'Description': pinfo['version'], 'Info': { 'LoadTemplateFromURL': pinfo['loadtemplatefromurl']},'Type': 'CLOUD_FORMATION_TEMPLATE','DisableTemplateValidation': True },IdempotencyToken=IdempotencyToken) _ret = {"ProductId":resp['ProductViewDetail']["ProductViewSummary"]["ProductId"],"ProvisioningArtifactId":resp['ProvisioningArtifactDetail']['Id'] } return _ret def s3getlist(bucket,Prefix): res = s3client.list_objects_v2(Bucket=bucket, Prefix=Prefix) key=[] if 'Contents' in res: for _content in res['Contents']: if _content['Key'].find('metadata') > -1: d= 0 else: key.append(_content['Key']) return key def gen_surl(bucketname, keyname): url = s3client.generate_presigned_url(ClientMethod='get_object', Params={'Bucket': bucketname, 'Key': keyname}) return url def bucket_putpriv_v1(bucket, key, acl): srep = s3client.put_object_acl(ACL=acl, Bucket=bucket, Key=key) return srep def bucket_putpriv(bucket, key, body,type): srep = s3client.put_object( ACL='private', Body=body, Bucket=bucket, Key=key, ContentType=type,) print(srep) return srep def bucket_get_obj(bucket, bkey): object = s3client.get_object(Bucket=bucket, Key=bkey) return(object['Body'].read().decode('utf-8')) def serveFiles(event, context): print(json.dumps(event)) _rhtml = '' ctype='text/html' try: bucket = os.environ['S3Bucket'] prefix = os.environ['prefix'] s3key = event['queryStringParameters']['s3key'] action = event['queryStringParameters']['action'] if action == 'wwwsvr': wwwkey = f'{prefix}{s3key}' print(wwwkey) ctype='text/html' if wwwkey.find('.js') > -1: ctype='text/javascript' if wwwkey.find('.css') > -1: ctype='text/css' if wwwkey.find('.json') > -1: ctype='text/json' _prehtml = bucket_get_obj(bucket,wwwkey) _rhtml = _prehtml except Exception as e: print(e) _rhtml = f'Error with {str(e)}' finally: response = { "statusCode": 200, "body": _rhtml, "headers": { 'Content-Type': ctype, }} return response def listdirectry(bucket,prefix): _ret=[] ret = s3client.list_objects_v2( Bucket=bucket, Delimiter=',', MaxKeys=123,Prefix=prefix) for key in ret['Contents']: keyarray =key['Key'].split('/') _scount = len(keyarray) _ret.append(keyarray[_scount-2]) _rret = list(set(_ret)) _rret.sort() _dircount = [] _ret2=[] for _dir in _rret: _ncount=0 _prefix = f'{prefix}{_dir}/' print(_prefix) _nret = s3client.list_objects_v2( Bucket=bucket, Delimiter=',', MaxKeys=123,Prefix=_prefix) if 'Contents' in _nret: _ncount = len(_nret['Contents']) _entry = f'{_dir}[{_ncount}]' _ret2.append(_entry) return _ret2 def listdirectryitems(bucket,prefix): _ret=[] ret = s3client.list_objects_v2( Bucket=bucket, Delimiter=',', MaxKeys=123,Prefix=prefix) for key in ret['Contents']: _ret.append(key['Key']) _ret.sort() return _ret def pollystartspeech(bucket,prefix,text,voice): rep = polly_client.start_speech_synthesis_task(Engine='neural',OutputFormat= 'mp3',OutputS3BucketName=bucket,OutputS3KeyPrefix=prefix,Text=text, VoiceId=voice) return rep['SynthesisTask']['OutputUri'] def scupdate(event): bucket = os.environ['S3bucket'] scproductname = os.environ['scproductname'] prefix = os.environ['prefix'] _ret =sc_find_product(scproductname) if _ret == "found": print('Updateing Product') _rand = random.randint(323, 24200) _srand = str(_rand) inputdir = f"{prefix}inputs/" print(inputdir) _listdir = listdirectry(bucket,inputdir) _listdir.append('update') servicetoken = event['ResourceProperties']['ServiceToken'] sc_pollyjson = json.loads(bucket_get_obj(bucket,'content/scpolly/sc_product_polly_new.json')) sc_pollyjson['Parameters']['InputFolder']['AllowedValues'] = _listdir print('Updating Product template') bucket_putpriv(bucket, 'content/scpolly/sc_product_polly_new.json', json.dumps(sc_pollyjson,indent=4) ,'text/json') newtemplate =f'https://{bucket}.s3.amazonaws.com/content/scpolly/sc_product_polly_new.json' _html= mgt_ent_sc_updateProduct(scproductname, newtemplate) return _html def bucketdeleteitems(bucket,object): response='failed' try: response = s3client.delete_objects(Bucket=bucket, Delete={'Objects':object,'Quiet': True}) except Exception as e: logging.error('Exception: %s' % e, exc_info=True) status = 'FAILED' return response def check_for_ses_email(event): awsregion = os.environ['AWS_REGION'] client = boto3.client('ses',region_name=awsregion) emails = client.list_verified_email_addresses() if event['etoemail'] in emails['VerifiedEmailAddresses']: print('Found ' + event['etoemail'] ) _ret = True else: response = client.verify_email_identity(EmailAddress= event['etoemail']) print('Email address not Found ' + event['etoemail'] +" Verification sent") _ret = False return _ret def lambda_handler(event, context): print(json.dumps(event)) timer = threading.Timer((context.get_remaining_time_in_millis()/ 1000.00) - 0.5, timeout, args=[event, context]) timer.start() status = 'SUCCESS' ret={} ret['emailmessage'] ='' bucket = os.environ['S3bucket'] scproductname = os.environ['scproductname'] region = os.environ['AWS_REGION'] prefix = os.environ['prefix'] ret['inputfolder'] = f'https://us-east-1.console.aws.amazon.com/s3/buckets/{bucket}?region={region}&prefix=content/scpolly/inputs/&showversions=false' try: if event['RequestType'] == 'Create': if event['ResourceProperties']['action'] == 'new': inputprefix = f'{prefix}inputs/' _listdir = listdirectry(bucket,inputprefix) _listdir.append('update') servicetoken = event['ResourceProperties']['ServiceToken'] sc_pollyjson = json.loads(bucket_get_obj(bucket,'content/scpolly/sc_product_polly.json')) sc_pollyjson['Parameters']['InputFolder']['AllowedValues'] = _listdir sc_pollyjson['Resources']['LambdaPollyRun']['Properties']['ServiceToken'] = servicetoken print('CreatingProduct template') bucket_putpriv(bucket, 'content/scpolly/sc_product_polly_new.json', json.dumps(sc_pollyjson,indent=4) ,'text/json') newtemplate =f'https://{bucket}.s3.amazonaws.com/content/scpolly/sc_product_polly_new.json' ret['loadtemplatefromurl'] = newtemplate if event['ResourceProperties']['action'] == 'update': _ret =sc_find_product(scproductname) if _ret == "found": print('Updating Product') _rand = random.randint(323, 24200) _srand = str(_rand) _listdir = listdirectry(bucket,prefix) _listdir.append('update') servicetoken = event['ResourceProperties']['ServiceToken'] sc_pollyjson = json.loads(bucket_get_obj(bucket,'content/scpolly/sc_product_polly_new.json')) sc_pollyjson['Parameters']['InputFolder']['AllowedValues'] = _listdir print('Updating Product template') bucket_putpriv(bucket, 'content/scpolly/sc_product_polly_new.json', json.dumps(sc_pollyjson,indent=4) ,'text/json') newtemplate =f'https://{bucket}.s3.amazonaws.com/content/scpolly/sc_product_polly_new.json' _html= mgt_ent_sc_updateProduct(scproductname, newtemplate) ret['loadtemplatefromurl'] = newtemplate if event['ResourceProperties']['action'] == 'polly': _folder = event['ResourceProperties']['inputfolder'] if _folder == "update": print("Updating folders") ret['outlink'] = 'Updated....' _newprod = scupdate(event) print(_newprod) else: _foldert = _folder.split('[')[0] prefixa = f'{prefix}inputs/{_foldert}/' prefixout = f'{prefix}outputs/{_foldert}/' texts = listdirectryitems(bucket,prefixa) _voices= ["Joanna","Ivy","Kevin","Matthew"] _bigret = [] pollyimg =f"{prefix}src/scpollyweb.png" pollyimg_surl =gen_surl(bucket,pollyimg) csskey=f"{prefix}src/table.css" print(csskey) csskeyg = gen_surl(bucket,csskey) _outhtml=f'
{txtkey} | Listen |