{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"QuickSight Batch Deployment\n",
"\n",
"Author: Ying Wang (Sr.Data Visualization Engineer in ProServe GSP)\n",
"Creation Date: April 16 2020\n",
"\n",
"Author: Vamsi Bhadriraju (Data Architect in ProServe) \n",
"Revision Date : January 12 2021\n",
"Revision Date : May 27 2021\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!pip install --upgrade pip\n",
"!pip install --upgrade boto3\n",
"get_ipython().system('pip install --upgrade ipynb')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import boto3\n",
"import json\n",
"import time\n",
"from IPython.display import JSON\n",
"import sys\n",
"import ipynb.fs \n",
"import logging\n",
"from typing import Any, Dict, List, Optional\n",
"from datetime import datetime\n",
"\n",
"# current date and time\n",
"now = str(datetime.now().strftime(\"%m-%d-%Y_%H_%M\"))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from ipynb.fs.defs.Functions import data_sources\n",
"from ipynb.fs.defs.Functions import describe_source \n",
"from ipynb.fs.defs.Functions import delete_source\n",
"from ipynb.fs.defs.Functions import create_data_source\n",
"from ipynb.fs.defs.Functions import get_datasource_name\n",
"from ipynb.fs.defs.Functions import get_datasource_ids\n",
"from ipynb.fs.defs.Functions import update_data_source_permissions\n",
"\n",
"from ipynb.fs.defs.Functions import get_dataset_name\n",
"from ipynb.fs.defs.Functions import data_sets\n",
"from ipynb.fs.defs.Functions import describe_dataset\n",
"from ipynb.fs.defs.Functions import get_dataset_ids\n",
"from ipynb.fs.defs.Functions import delete_dataset \n",
"from ipynb.fs.defs.Functions import create_dataset\n",
"from ipynb.fs.defs.Functions import update_dataset\n",
"from ipynb.fs.defs.Functions import update_data_set_permissions\n",
"\n",
"from ipynb.fs.defs.Functions import get_target\n",
"\n",
"from ipynb.fs.defs.Functions import templates\n",
"from ipynb.fs.defs.Functions import delete_template\n",
"from ipynb.fs.defs.Functions import update_template_permission \n",
"from ipynb.fs.defs.Functions import copy_template\n",
"from ipynb.fs.defs.Functions import describe_template\n",
"from ipynb.fs.defs.Functions import create_template \n",
"\n",
"from ipynb.fs.defs.Functions import dashboards\n",
"from ipynb.fs.defs.Functions import describe_dashboard\n",
"from ipynb.fs.defs.Functions import create_dashboard \n",
"from ipynb.fs.defs.Functions import delete_dashboard\n",
"from ipynb.fs.defs.Functions import update_dashboard \n",
"from ipynb.fs.defs.Functions import get_dashboard_ids\n",
"from ipynb.fs.defs.Functions import get_dashboard_name\n",
"\n",
"from ipynb.fs.defs.Functions import themes\n",
"from ipynb.fs.defs.Functions import describe_theme\n",
"from ipynb.fs.defs.Functions import delete_theme\n",
"from ipynb.fs.defs.Functions import create_theme\n",
"from ipynb.fs.defs.Functions import update_theme\n",
"from ipynb.fs.defs.Functions import describe_theme_permissions\n",
"from ipynb.fs.defs.Functions import update_theme_permissions\n",
"\n",
"\n",
"from ipynb.fs.defs.Functions import analysis\n",
"from ipynb.fs.defs.Functions import describe_analysis\n",
"from ipynb.fs.defs.Functions import create_analysis\n",
"from ipynb.fs.defs.Functions import delete_analysis\n",
"from ipynb.fs.defs.Functions import update_analysis\n",
"from ipynb.fs.defs.Functions import get_analysis_ids\n",
"from ipynb.fs.defs.Functions import describe_analysis_permissions\n",
"\n",
"\n",
"\n",
"#supportive functions\n",
"from ipynb.fs.defs.Functions import data_sets_ls_of_dashboard\n",
"from ipynb.fs.defs.Functions import data_sources_ls_of_dashboard\n",
"from ipynb.fs.defs.Functions import get_data_source_deployment_list\n",
"from ipynb.fs.defs.Functions import data_sources_ls_of_analysis\n",
"from ipynb.fs.defs.Functions import data_sets_ls_of_analysis\n",
"from ipynb.fs.defs.Functions import get_user_arn\n",
"from ipynb.fs.defs.Functions import _assume_role\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Static Profile\n",
"\n",
"You can configure AWS profile from terminal and call the profile in below cell"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sourceprofile=''\n",
"targetprofile=''\n",
"aws_region='us-east-1'\n",
"sourcesession = boto3.Session(profile_name=sourceprofile, region_name=aws_region)\n",
"targetsession = boto3.Session(profile_name=targetprofile, region_name=aws_region)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Assume Role\n",
"\n",
"You can also assume an IAM role and create session based on the role permissions"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#source account\n",
"sourceaccountid=\n",
"role_name=\n",
"aws_region='us-east-1'\n",
"sourcesession = _assume_role(sourceaccountid, role_name, aws_region)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#target account\n",
"targetaccountid=\"\"\n",
"role_name=\"\"\n",
"aws_region='us-east-1'\n",
"targetsession = _assume_role(targetaccountid, role_name, aws_region)\n",
"#targetsession = boto3.Session(\n",
"# aws_access_key_id=\"\",\n",
"# aws_secret_access_key=\"\",\n",
"# aws_session_token=\"\",\n",
"# region_name=aws_region\n",
"# )"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Set root and admin users\n",
"\n",
"root user is for the template. \n",
"By default, we assign full permissions of objects to admin."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def get_user_arn (session, username, region='us-east-1', namespace='default'): \n",
" sts_client = session.client(\"sts\")\n",
" account_id = sts_client.get_caller_identity()[\"Account\"]\n",
" if username=='root':\n",
" arn='arn:aws:iam::'+account_id+':'+username\n",
" else:\n",
" arn=\"arn:aws:quicksight:\"+region+\":\"+account_id+\":user/\"+namespace+\"/\"+username\n",
" \n",
" return arn\n",
" \n",
"sourceroot=get_user_arn (sourcesession, 'root')\n",
"sourceadmin=get_user_arn (sourcesession, 'Administrator/wangzyn-Isengard')\n",
"#sourceversion='1'\n",
"\n",
"targetroot=get_user_arn (targetsession, 'root')\n",
"targetadmin=get_user_arn (targetsession, 'Admin/wangzyn-Isengard')\n",
"#targetvpc='arn:aws:quicksight:us-east-1:889399602426:vpcConnection/sg-40b7521a'"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Please define your input parameters in below cell"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"rds='wangzynrds.adrcdferg.us-east-1.rds.amazonaws.com'\n",
"redshift={\n",
" \"ClusterId\": 'wangzyncluster1',\n",
" \"Host\": 'wangzyncluster1.coprq8ycemvc.us-east-1.redshift.amazonaws.com',\n",
" \"Database\": 'dev'}\n",
"\n",
"s3Bucket='spaceneedle-samplefiles.prod.us-east-1'\n",
"s3Key='sales/manifest.json'\n",
"vpc='sg-40b7521a'\n",
"tag=[\n",
" {\n",
" 'Key': 'test',\n",
" 'Value': 'true'\n",
" }\n",
" ]\n",
"owner=targetadmin\n",
"rdscredential={\n",
" 'CredentialPair': {\n",
" 'Username': \"\",\n",
" 'Password': \"\"}}\n",
"redshiftcredential={\n",
" 'CredentialPair': {\n",
" 'Username': \"\",\n",
" 'Password': \"\"}}\n",
"region='us-east-1'\n",
"namespace='default'\n",
"version='1' \n",
"\n",
"target=get_target(targetsession, rds,redshift,s3Bucket,s3Key,vpc,tag,owner,rdscredential,redshiftcredential)\n",
"\n",
"#JSON(target)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#results output location\n",
"successlocation = \"Deployment_Results/Successful/\"\n",
"faillocation = \"Deployment_Results/Fail/\"\n",
"\n",
"import os\n",
"try:\n",
" os.makedirs(successlocation)\n",
"except OSError:\n",
" print (\"Creation of the directory %s failed\" % successlocation)\n",
"else:\n",
" print (\"Successfully created the directory %s\" % successlocation)\n",
"\n",
"try:\n",
" os.makedirs(faillocation)\n",
"except OSError:\n",
" print (\"Creation of the directory %s failed\" % faillocation)\n",
"else:\n",
" print (\"Successfully created the directory %s\" % faillocation)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Import functions from Functions.ipynb"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"New Account Set Up Sample"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Deploy data sources"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#data_sources function will return all the data sources of a specific AWS Account\n",
"#data_sources ('Account ID', profile)\n",
"\n",
"#new account set up sample:\n",
"datasources=data_sources(sourcesession)\n",
"\n",
"#get data sources which already deployed\n",
"targetsources=data_sources(targetsession)\n",
"\n",
"#already_deployed record the data source ids of target account\n",
"already_deployed=[]\n",
"for tsource in targetsources:\n",
" already_deployed.append(tsource['DataSourceId'])\n",
" \n",
"newsourceslist=[]\n",
"faillist=[]\n",
"for i in datasources:\n",
" if i['DataSourceId'] not in already_deployed and 'DataSourceParameters' in i:\n",
" newdsource=create_data_source (i, targetsession, target)\n",
" if 'Error' in newdsource:\n",
" faillist.append(newdsource)\n",
" \n",
" else: newsourceslist.append(newdsource)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"with open(faillocation+now+'_Datasource_Creation_Error.json', \"w\") as f:\n",
" json.dump(faillist, f, indent=4, sort_keys=True, default=str)\n",
"\n",
"faillist2=[]\n",
"successfulls=[]\n",
"for news in newsourceslist:\n",
" datasource=describe_source(targetsession, news['DataSourceId'])\n",
"\n",
" if datasource['DataSource']['Status']==\"CREATION_FAILED\":\n",
" delete_source (targetsession, news['DataSourceId'])\n",
" faillist2.append(news['DataSourceId'])\n",
" \n",
" if datasource['DataSource']['Status']==\"CREATION_SUCCESSFUL\":\n",
" successfulls.append(datasource['DataSource'])\n",
" \n",
" while datasource['DataSource']['Status']==\"CREATION_IN_PROGRESS\":\n",
" time.sleep(5)\n",
" datasource=describe_source(targetsession, news['DataSourceId'])\n",
" if datasource['DataSource']['Status']==\"CREATION_SUCCESSFUL\":\n",
" successfulls.append(datasource['DataSource'])\n",
" break\n",
" elif datasource['DataSource']['Status']==\"CREATION_FAILED\":\n",
" delete_source (targetsession, news['DataSourceId'])\n",
" faillist2.append(news['DataSourceId'])\n",
" \n",
"with open(faillocation+now+'_Datasource_Creation_Fail.json', \"w\") as f:\n",
" json.dump(faillist2, f, indent=4, sort_keys=True, default=str)\n",
"\n",
"with open(successlocation+now+'_Datasource_Creation_Success.json', \"w\") as f:\n",
" json.dump(successfulls, f, indent=4, sort_keys=True, default=str)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Delete objects"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# THIS WILL DELETE ALL TARGET DATASETS\n",
"\n",
"delete = \"datasource\"\n",
"\n",
"if delete == \"datasource\": \n",
" for datasource in data_sources(targetsession):\n",
" #if datasource['Type'] == \"REDSHIFT\":\n",
" try:\n",
" delete_source (targetsession, datasource['DataSourceId'])\n",
" except Exception: pass \n",
"elif delete == \"dataset\":\n",
" for dataset in data_sets(targetsession):\n",
" delete_dataset (targetsession, dataset['DataSetId'])\n",
"elif delete == \"template\": \n",
" for template in templates(targetsession):\n",
" delete_template(targetsession, template['TemplateId'])\n",
"elif delete == \"analysis\":\n",
" for analysis in analysis(targetsession): delete_analysis(targetsession, analysis['AnalysisId'])\n",
" \n",
"elif delete == \"dashboard\": \n",
" for dashboard in dashboards(targetsession):\n",
" delete_dashboard(targetsession, dashboard['DashboardId'])\n",
"delete =\"don't delete anything\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Get datasets list:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"datasets=data_sets(sourcesession)\n",
"#JSON(datasets)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Deploy Datasets"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#get datasets which already deployed\n",
"targetds=data_sets(targetsession)\n",
"#already_deployed record the datasets ids of target account\n",
"already_deployed=[]\n",
"for ds in targetds:\n",
" already_deployed.append(ds['DataSetId'])\n",
"#already_deployed"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"newsetslist=[]\n",
"faillist=[]\n",
"sts_client = targetsession.client(\"sts\")\n",
"account_id = sts_client.get_caller_identity()[\"Account\"]\n",
"for i in datasets:\n",
" if i['DataSetId'] not in already_deployed:\n",
" try:\n",
" res=describe_dataset(sourcesession, i['DataSetId'])\n",
" except Exception:\n",
" faillist.append({\"Dataset\": i, \"Error\": str(Exception)})\n",
" continue\n",
" #if 's3PhysicalTable' in res['DataSet']['PhysicalTableMap']:\n",
" #continue\n",
" #else:\n",
" #pass\n",
"\n",
" \n",
" name=i['Name'].replace(\" \", \"_\")\n",
" datasetid=i['DataSetId']\n",
"\n",
" PT=res['DataSet']['PhysicalTableMap']\n",
" # print(PT)\n",
" for key, value in PT.items():\n",
" #print(value)\n",
" for i,j in value.items():\n",
" #print(j)\n",
" dsid = j['DataSourceArn'].split(\"/\")[1]\n",
" j['DataSourceArn']='arn:aws:quicksight:us-east-1:'+account_id+':datasource/'+dsid\n",
"\n",
" LT=res['DataSet']['LogicalTableMap']\n",
" \n",
" try: \n",
" newdataset=create_dataset(targetsession, datasetid, name, PT, LT, res['DataSet']['ImportMode'], target['datasetpermission'])\n",
" #print(\"new dataset: \", newdataset)\n",
" newsetslist.append(newdataset)\n",
" except Exception as e:\n",
" #print('failed: '+str(e))\n",
" faillist.append({\"DataSetId\": datasetid, \"Name\": name, \"Error\": str(e)})\n",
" \n",
" continue"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#print fail informations\n",
"with open(faillocation+now+'Dataset_Creation_Error.json', \"w\") as f:\n",
" json.dump(faillist, f, indent=4, sort_keys=True, default=str)\n",
"\n",
"successfulls=[]\n",
"for news in newsetslist:\n",
" dataset=describe_dataset(targetsession, news['DataSetId'])\n",
" successfulls.append(dataset['DataSet'])\n",
" \n",
"with open(successlocation+now+'Datasets_Creation_Success.json', \"w\") as f:\n",
" json.dump(successfulls, f, indent=4, sort_keys=True, default=str)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Get Themes List"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"themes_list =themes(sourcesession)\n",
"#JSON(datasets)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Deploy Themes"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#get themes which already deployed\n",
"targetthemes=themes(targetsession)\n",
"#already_deployed record the datasets ids of target account\n",
"already_deployed=[]\n",
"for th in targetthemes:\n",
" already_deployed.append(th['ThemeId'])\n",
"#already_deployed"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"newthemeslist=[]\n",
"faillist=[]\n",
"sts_client = targetsession.client(\"sts\")\n",
"account_id = sts_client.get_caller_identity()[\"Account\"]\n",
"for i in themes_list:\n",
" if i['ThemeId'] not in already_deployed:\n",
" try:\n",
" res=describe_theme(sourcesession, i['ThemeId'])\n",
" except Exception:\n",
" faillist.append({\"Theme\": i, \"Error\": str(Exception)})\n",
" continue\n",
" THEMEID=res['Theme']['ThemeId']\n",
" Name=res['Theme']['Name']\n",
" BaseThemeId=res['Theme']['Version']['BaseThemeId']\n",
" Configuration=res['Theme']['Version']['Configuration']\n",
" try: \n",
" newtheme=create_theme (targetsession,THEMEID, Name,BaseThemeId,Configuration)\n",
" newthemeslist.append(newtheme)\n",
" except Exception as e:\n",
" #print('failed: '+str(e))\n",
" faillist.append({\"ThemeID\": THEMEID, \"Name\": Name, \"Error\": str(e)})\n",
" continue\n",
" try:\n",
" update_theme_permissions(targetsession, THEMEID, targetadmin)\n",
" except Exception as e:\n",
" #print('failed: '+str(e))\n",
" faillist.append({\"ThemeID\": THEMEID, \"Name\": Name, \"Error\": str(e)})\n",
" continue"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
" \n",
"#print fail informations\n",
"with open(faillocation+now+'Themes_Creation_Error.json', \"w\") as f:\n",
" json.dump(faillist, f, indent=4, sort_keys=True, default=str)\n",
"\n",
"successfulls=[]\n",
"for news in newthemeslist:\n",
" theme=describe_theme(targetsession, news['ThemeId'])\n",
" successfulls.append(theme['Theme']['ThemeId'])\n",
" \n",
"with open(successlocation+now+'Themes_Creation_Success.json', \"w\") as f:\n",
" json.dump(successfulls, f, indent=4, sort_keys=True, default=str)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Get Analysis list"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sourceanalysis_list=analysis(sourcesession)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Deploy Analysis"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sourceanalysis_all=[]\n",
"for i in sourceanalysis_list:\n",
" if i['Status']!= 'DELETED':\n",
" sourceanalysis_all.append(i)\n",
"\n",
"success=[]\n",
"faillist=[]\n",
"sts_client = targetsession.client(\"sts\")\n",
"account_id = sts_client.get_caller_identity()[\"Account\"]\n",
"for i in sourceanalysis_all:\n",
" sourceanalysis=describe_analysis(sourcesession, i['AnalysisId'])\n",
" sourceanalysisid=sourceanalysis['Analysis']['AnalysisId']\n",
" sourceanalysisArn=sourceanalysis['Analysis']['Arn']\n",
" sourceanalysisname=sourceanalysis['Analysis']['Name']\n",
" DataSetArns=sourceanalysis['Analysis']['DataSetArns']\n",
" sourcetid=sourceanalysisid\n",
" sourcetname=sourceanalysisname\n",
" targettid=sourcetid\n",
" targettname=sourceanalysisname\n",
" \n",
" TargetThemeArn=''\n",
" if 'ThemeArn' in sourceanalysis['Analysis'].keys():\n",
" SourceThemeArn=sourceanalysis['Analysis']['ThemeArn']\n",
" TargetThemeArn = 'arn:aws:quicksight:'+region+':'+account_id+':theme/'+sourceanalysis['Analysis']['ThemeArn'].split(\"/\")[1]\n",
"\n",
" sourcedsref = []\n",
" for i in DataSetArns:\n",
" missing=False\n",
" did = i.split(\"/\")[1]\n",
" try:\n",
" dname=get_dataset_name(did, sourcesession)\n",
" except Exception as e:\n",
" faillist.append({\"Error Type\": \"Dataset: \"+did+\" is missing!\",\"sourceanalysisid\": sourcetid, \"Name\": sourcetname, \"Error\": str(e)})\n",
" missing=True\n",
" break\n",
" \n",
" sourcedsref.append({'DataSetPlaceholder': dname,\n",
" 'DataSetArn': i})\n",
" if missing: continue\n",
" try:\n",
" sourcetemplate = create_template(sourcesession, sourcetid, sourcetname, sourcedsref, sourceanalysisArn, '1')\n",
" sourcetemplate=describe_template(sourcesession,sourcetid)\n",
" except Exception as e:\n",
" faillist.append({\"Error Type\": \"Create Source Template Error\",\"sourceanalysisid\": sourcetid, \"Name\": sourcetname, \"Error\": str(e)})\n",
"\n",
" continue\n",
" \n",
" while sourcetemplate['Template']['Version']['Status']==\"CREATION_IN_PROGRESS\":\n",
" time.sleep(5)\n",
" sourcetemplate=describe_template(sourcesession,sourcetid)\n",
" if sourcetemplate['Template']['Version']['Status']==\"CREATION_SUCCESSFUL\":\n",
" try:\n",
" updateres=update_template_permission(sourcesession, sourcetid, targetroot)\n",
" except Exception as e:\n",
" delete_template(sourcesession, sourcetid)\n",
" faillist.append({\"Error Type\": \"Update Source Template Permission Error\",\n",
" \"sourceanalysisid\": sourcetid, \n",
" \"Name\": sourcetname, \n",
" \"Error\": str(e)})\n",
" else: \n",
" if sourcetemplate['Template']['Version']['Status']==\"CREATION_SUCCESSFUL\":\n",
" try:\n",
" updateres=update_template_permission(sourcesession, sourcetid, targetroot)\n",
" except Exception as e:\n",
" delete_template(sourcesession, sourcetid)\n",
" faillist.append({\"Error Type\": \"Update Source Template Permission Error\",\n",
" \"sourceanalysisid\": sourcetid, \n",
" \"Name\": sourcetname, \n",
" \"Error\": str(e)})\n",
" continue \n",
"\n",
" ds=data_sets (targetsession)\n",
" Template=sourcetemplate['Template']\n",
" dsref=[]\n",
" \n",
" missing=False\n",
" for i in Template['Version']['DataSetConfigurations']:\n",
" #print(i)\n",
" n=Template['Version']['DataSetConfigurations'].index(i)\n",
" #print(n)\n",
" for j in ds:\n",
" if i['Placeholder']==j['Name']:\n",
" dsref.append({\n",
" 'DataSetPlaceholder': i['Placeholder'],\n",
" 'DataSetArn': j['Arn']\n",
" })\n",
" if n>len(dsref): \n",
" e=\"Dataset \"+i['Placeholder']+\"is missing!\"\n",
" faillist.append({\"Error Type\": \"Datasets in target env are missing for this analysis\",\n",
" \"sourceanalysisid\": sourcetid, \n",
" \"Name\": sourcetname, \n",
" \"Error\": str(e)})\n",
" missing=True\n",
" break\n",
" if missing: break\n",
" if missing: continue\n",
" \n",
"##working\n",
" SourceEntity={\n",
" 'SourceTemplate': {\n",
" 'DataSetReferences': dsref,\n",
" 'Arn': Template['Arn']\n",
" }\n",
" }\n",
" \n",
" #print(SourceEntity)\n",
" analysis=describe_analysis(targetsession, targettid)\n",
" if 'Faild to describe analysis:' in analysis or analysis['Analysis']['Status']=='DELETED':\n",
" if 'analysis/'+targettid+' is not found' in analysis or analysis['Analysis']['Status']=='DELETED':\n",
" print(\"Create new anlaysis now:\")\n",
" try:\n",
" newanalysis=create_analysis(targetsession, targettid, targettname,targetadmin,SourceEntity,TargetThemeArn)\n",
" except Exception as e:\n",
" delete_template(sourcesession, targettid)\n",
" faillist.append({\"Error Type\": \"Create New Analysis Error\",\n",
" \"AnalysisID\": targettid, \n",
" \"Name\": targettname, \n",
" \"Error\": str(e)}) \n",
" continue\n",
" else:\n",
" faillist.append({\"Error Type\": \"Describe Target Analysis Error\",\n",
" \"AnalysisID\": targettid, \n",
" \"Name\": targettname, \n",
" \"Error\": str(analysis)}) \n",
" continue\n",
" elif analysis['Analysis']['Status']==\"CREATION_FAILED\":\n",
" res=delete_analysis(sourcesession, targettid)\n",
" try:\n",
" newanalysis=create_analysis(targetsession, targettid, targettname,targetadmin, SourceEntity,TargetThemeArn)\n",
" except Exception as e:\n",
" delete_template(sourcesession, targettid)\n",
" faillist.append({\"Error Type\": \"Create Analysis Error\",\n",
" \"AnalysisID\": targettid, \n",
" \"Name\": targettname, \n",
" \"Error\": str(e)})\n",
" continue\n",
" \n",
" else:\n",
" print(\"analysis is existing. update it now.\")\n",
" try:\n",
" newanalysis=update_analysis(targetsession, targettid, targettname, SourceEntity,TargetThemeArn)\n",
" except Exception as e:\n",
" delete_template(sourcesession, targettid)\n",
" faillist.append({\"Error Type\": \"Update Analysis Error\",\n",
" \"AnalysisID\": targettid, \n",
" \"Name\": targettname, \n",
" \"Error\": str(e)})\n",
" continue\n",
" time.sleep(20)\n",
" res=describe_analysis(targetsession,newanalysis['AnalysisId'])\n",
" if res['Status']==200:\n",
" status=res['Analysis']['Status']\n",
" if status=='CREATION_SUCCESSFUL' or status=='UPDATE_SUCCESSFUL':\n",
" success.append(res['Analysis'])\n",
" #filename=\"Deployment_Results/Successful/Analysis_\"+res['Analysis']['Name']+\".json\"\n",
" else:\n",
" faillist.append({\"Error Type\": \"Analysis Creation Status is not Successful\", \"Analysis\": res['Analysis']})\n",
" #filename=\"Deployment_Results/Fail/Analysis_\"+res['Analysis']['Name']+\".json\""
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"with open(faillocation+now+'Analysis_Error.json', \"w\") as f:\n",
" json.dump(faillist, f, indent=4, sort_keys=True, default=str)\n",
"\n",
"with open(successlocation+now+'Analysis_Success.json', \"w\") as f:\n",
" json.dump(success, f, indent=4, sort_keys=True, default=str)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Get dashboards list"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sourcedashboards=dashboards(sourcesession)\n",
"#dashboards"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Deploy dashboards"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"success=[]\n",
"faillist=[]\n",
"for i in sourcedashboards:\n",
" sourcedashboard=describe_dashboard(sourcesession, i['DashboardId'])\n",
" SourceEntityArn=sourcedashboard['Dashboard']['Version']['SourceEntityArn']\n",
" if SourceEntityArn.split(\"/\")[0].split(\":\")[-1]==\"analysis\":\n",
" sourceanalysis=sourcedashboard['Dashboard']['Version']['SourceEntityArn']\n",
" else: \n",
" faillist.append({\"Error Type\": \"Source Analysis is missing!\",\"DashboardId\": sourcetid, \"Name\": sourcetname, \"Error\": \"Source Analysis is missing!\"})\n",
" continue\n",
" sourceversion=sourcedashboard['Dashboard']['Version']['VersionNumber']\n",
" sourcedid=sourcedashboard['Dashboard']['DashboardId']\n",
" sourcedname=sourcedashboard['Dashboard']['Name']\n",
" sourcetid=sourcedid\n",
" sourcetname=sourcedname\n",
" targettid=sourcetid\n",
" targettname=sourcedname\n",
" DataSetArns=sourcedashboard['Dashboard']['Version']['DataSetArns']\n",
" TargetThemeArn=''\n",
" if 'ThemeArn' in sourcedashboard['Dashboard']['Version'].keys():\n",
" SourceThemearn=sourcedashboard['Dashboard']['Version']['ThemeArn']\n",
" TargetThemeArn = 'arn:aws:quicksight:'+region+':'+account_id+':theme/'+SourceThemearn.split(\"/\")[1]\n",
" sourcedsref = []\n",
" #print(sourcedname)\n",
" for i in DataSetArns:\n",
" missing=False\n",
" did = i.split(\"/\")[1]\n",
" #print(did)\n",
" try:\n",
" dname=get_dataset_name(did, sourcesession)\n",
" except Exception as e:\n",
" faillist.append({\"Error Type\": \"Dataset: \"+did+\" is missing!\",\"DashboardId\": sourcetid, \"Name\": sourcetname, \"Error\": str(e)})\n",
" missing=True\n",
" break\n",
" \n",
" sourcedsref.append({'DataSetPlaceholder': dname,\n",
" 'DataSetArn': i})\n",
" if missing: continue\n",
" try:\n",
" sourcetemplate = create_template(sourcesession, sourcetid, sourcetname, sourcedsref, sourceanalysis, '1')\n",
" sourcetemplate=describe_template(sourcesession,sourcetid)\n",
" except Exception as e:\n",
" faillist.append({\"Error Type\": \"Create Source Template Error\",\"DashboardId\": sourcetid, \"Name\": sourcetname, \"Error\": str(e)})\n",
" continue\n",
" \n",
" while sourcetemplate['Template']['Version']['Status']==\"CREATION_IN_PROGRESS\":\n",
" time.sleep(5)\n",
" sourcetemplate=describe_template(sourcesession,sourcetid)\n",
" if sourcetemplate['Template']['Version']['Status']==\"CREATION_SUCCESSFUL\":\n",
" try:\n",
" updateres=update_template_permission(sourcesession, sourcetid, targetroot)\n",
" except Exception as e:\n",
" delete_template(sourcesession, sourcetid)\n",
" faillist.append({\"Error Type\": \"Update Source Template Permission Error\",\n",
" \"DashboardId\": sourcetid, \n",
" \"Name\": sourcetname, \n",
" \"Error\": str(e)})\n",
" else: \n",
" if sourcetemplate['Template']['Version']['Status']==\"CREATION_SUCCESSFUL\":\n",
" try:\n",
" updateres=update_template_permission(sourcesession, sourcetid, targetroot)\n",
" except Exception as e:\n",
" delete_template(sourcesession, sourcetid)\n",
" faillist.append({\"Error Type\": \"Update Source Template Permission Error\",\n",
" \"DashboardId\": sourcetid, \n",
" \"Name\": sourcetname, \n",
" \"Error\": str(e)})\n",
" continue\n",
"\n",
" if updateres['Status']==200:\n",
" try:\n",
" targettemplate=copy_template(targetsession, targettid, targettname, updateres['TemplateArn'])\n",
" except Exception as e:\n",
" delete_template(sourcesession, sourcetid)\n",
" faillist.append({\"Error Type\": \"Copy Template Error\",\n",
" \"DashboardId\": sourcetid, \n",
" \"Name\": sourcetname, \n",
" \"Error\": str(e)}) \n",
" continue\n",
" else: \n",
" delete_template(sourcesession, sourcetid)\n",
" faillist.append({\"Error Type\": \"Update Source Template Permission Error\",\n",
" \"DashboardId\": sourcetid, \n",
" \"Name\": sourcetname, \n",
" \"Error\": str(e)})\n",
" continue\n",
" \n",
" targettemplate=describe_template(targetsession,targettid)\n",
" \n",
" while targettemplate['Template']['Version']['Status']==\"CREATION_IN_PROGRESS\":\n",
" time.sleep(5)\n",
" targettemplate=describe_template(targetsession,targettid)\n",
" if targettemplate['Template']['Version']['Status']==\"CREATION_SUCCESSFUL\":\n",
" break\n",
" else: \n",
" if targettemplate['Template']['Version']['Status']==\"CREATION_SUCCESSFUL\":\n",
" print(\"Template is successful copied!\")\n",
" else: \n",
" delete_template(targetsession, targettid)\n",
" faillist.append({\"Error Type\": \"Copy Template Error\",\n",
" \"DashboardId\": sourcetid, \n",
" \"Name\": sourcetname, \n",
" \"Error\": str(e)})\n",
" continue\n",
" \n",
" ds=data_sets (targetsession)\n",
" Template=targettemplate['Template']\n",
" dsref=[]\n",
" \n",
" missing=False\n",
" for i in Template['Version']['DataSetConfigurations']:\n",
" #print(i)\n",
" n=Template['Version']['DataSetConfigurations'].index(i)\n",
" #print(n)\n",
" for j in ds:\n",
" if i['Placeholder']==j['Name']:\n",
" dsref.append({\n",
" 'DataSetPlaceholder': i['Placeholder'],\n",
" 'DataSetArn': j['Arn']\n",
" })\n",
" if n>len(dsref): \n",
" e=\"Dataset \"+i['Placeholder']+\"is missing!\"\n",
" faillist.append({\"Error Type\": \"Datasets in target env are missing for this dashboard\",\n",
" \"DashboardId\": sourcetid, \n",
" \"Name\": sourcetname, \n",
" \"Error\": str(e)})\n",
" missing=True\n",
" break\n",
" if missing: break\n",
" if missing: continue\n",
" \n",
" SourceEntity={\n",
" 'SourceTemplate': {\n",
" 'DataSetReferences': dsref,\n",
" 'Arn': Template['Arn']\n",
" }\n",
" }\n",
" #print(SourceEntity)\n",
" dashboard=describe_dashboard(targetsession, targettid)\n",
"\n",
" if 'Faild to describe dashboard:' in dashboard:\n",
" if 'dashboard/'+targettid+' is not found' in dashboard:\n",
" print(\"Create new dashboard now:\")\n",
" try:\n",
" newdashboard=create_dashboard(targetsession, targettid, targettname,targetadmin, SourceEntity, '1',TargetThemeArn,filter='ENABLED',csv='ENABLED', sheetcontrol='COLLAPSED')\n",
" except Exception as e:\n",
" delete_template(targetsession, targettid)\n",
" faillist.append({\"Error Type\": \"Create New Dashboard Error\",\n",
" \"DashboardId\": targettid, \n",
" \"Name\": targettname, \n",
" \"Error\": str(e)}) \n",
" continue\n",
" else: \n",
" faillist.append({\"Error Type\": \"Describe Target Dashboard Error\",\n",
" \"DashboardId\": targettid, \n",
" \"Name\": targettname, \n",
" \"Error\": str(dashboard)}) \n",
" continue\n",
" elif dashboard['Dashboard']['Version']['Status']==\"CREATION_FAILED\":\n",
" res=delete_dashboard(targetsession, targettid)\n",
" try:\n",
" newdashboard=create_dashboard(targetsession, targettid, targettname,targetadmin, SourceEntity, '1',TargetThemeArn,filter='ENABLED',csv='ENABLED', sheetcontrol='COLLAPSED')\n",
" except Exception as e:\n",
" delete_template(targetsession, targettid)\n",
" faillist.append({\"Error Type\": \"Create Dashboard Error\",\n",
" \"DashboardId\": targettid, \n",
" \"Name\": targettname, \n",
" \"Error\": str(e)})\n",
" continue\n",
" \n",
" else:\n",
" print(\"dashboard is existing. Delete and recreate it now.\")\n",
" try:\n",
" res=delete_dashboard(targetsession, targettid)\n",
" newdashboard=create_dashboard(targetsession, targettid, targettname,targetadmin, SourceEntity, '1',TargetThemeArn,filter='ENABLED',csv='ENABLED', sheetcontrol='COLLAPSED')\n",
" except Exception as e:\n",
" delete_template(targetsession, targettid)\n",
" faillist.append({\"Error Type\": \"Create Dashboard Error\",\n",
" \"DashboardId\": targettid, \n",
" \"Name\": targettname, \n",
" \"Error\": str(e)})\n",
" continue\n",
"\n",
" res=describe_dashboard(targetsession,newdashboard['DashboardId'])\n",
" \n",
" if res['Status']==200:\n",
" status=res['Dashboard']['Version']['Status']\n",
" if status=='CREATION_SUCCESSFUL' or status=='UPDATE_SUCCESSFUL':\n",
" success.append(res['Dashboard'])\n",
" #filename=\"Deployment_Results/Successful/Dashboard_\"+res['Dashboard']['Name']+\".json\"\n",
" else:\n",
" faillist.append({\"Error Type\": \"Dashboard Creation Status is not Successful\", \"Dashboard\": res['Dashboard']})\n",
"\n",
" #filename=\"Deployment_Results/Fail/Dashboard_\"+res['Dashboard']['Name']+\".json\""
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"with open(faillocation+now+'Dashboard_Error.json', \"w\") as f:\n",
" json.dump(faillist, f, indent=4, sort_keys=True, default=str)\n",
"\n",
"with open(successlocation+now+'Dashboard_Success.json', \"w\") as f:\n",
" json.dump(success, f, indent=4, sort_keys=True, default=str)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Schedule notebooks to execute"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"https://aws.amazon.com/blogs/machine-learning/scheduling-jupyter-notebooks-on-sagemaker-ephemeral-instances/"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.4"
},
"toc-showcode": false,
"toc-showmarkdowntxt": true
},
"nbformat": 4,
"nbformat_minor": 4
}