Automate Password Updates using Python for Workbooks, datasources and flows

            Most of the Companies adhere to password policy of 60-90 days . Tableau workbooks, Datasources and Flows needs to have the DB password updated adhering to the policy. 

           I want to make an executable that makes easy to change the passwords. Here is the new Executable that helps to change the passwords in tableau objects.


import tableauserverclient as TSC

import argparse ,os, configparser, re

from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter

import logging

import datetime

CONFIGURATION_FILE="passwordconfig.txt" #configuration file name and path. 

#Copy the config file from the below 


#logmodule

def create_logger(log_id):

    logger = logging.getLogger(log_id)

    logger.setLevel(logging.DEBUG)

    fh = logging.FileHandler(filename="passwordchangelog.txt") #log filename and its path

    fh.setLevel(logging.DEBUG)

    fh.setFormatter( logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') )

    logger.addHandler(fh)


    sh = logging.StreamHandler()

    sh.setLevel(logging.INFO)

    sh.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))

    logger.addHandler(sh)


    log = logging.getLogger(log_id)

    return log

logid="message"

log = create_logger(logid)


#global file_configs.get

if not os.path.isfile(CONFIGURATION_FILE):

    log.error("Config file not found")

    raise Exception("Configuration file not found")

file_configs = configparser.ConfigParser()

file_configs.read(CONFIGURATION_FILE, encoding='utf-8')

# for section in file_configs.sections():

#     file_configs.get(section) = {}

#     print(file_configs.get(section))

request_options = TSC.RequestOptions(pagesize=1000)


search_server = file_configs.get("server","search_server")

search_server_regex = search_server.replace('.','\.') # replace periods with escape character

replace_server = file_configs.get("server","search_server")

overwrite_credentials = file_configs.get("server","overwrite_credentials")

search_for_certain_users = file_configs.get("server","search_for_certain_users")

search_username = file_configs.get("server","search_username")

replace_username = file_configs.get("server","search_username")

replace_pw = file_configs.get("server","new_pw")

x=0=0

z=0

#Tableau Login Details

tableau_auth = TSC.TableauAuth(file_configs.get("server","adminusername"), file_configs.get("server","adminpw"), site_id=file_configs.get("server","site"))

server=TSC.Server(file_configs.get("server","target_server"))

server.add_http_options({'verify':file_configs.get("server","cert")})

server.version='3.15'


try:

    with server.auth.sign_in(tableau_auth):

        print("loggedin")

        all_datasources, pagination_item=server.datasources.get(req_options=request_options)

        print("Total Datasources:{}".format(len(all_datasources)))

        for datasource in all_datasources:

            server.datasources.populate_connections(datasource)


            for item,conn in enumerate(datasource.connections):


                if re.search(search_server_regex, datasource.connections[item].server_address,re.IGNORECASE):

                    print("DS")

                    connection=datasource.connections[item]

                    log.info(datasource.name)

                    log.info(datasource.project_name)

                    #log.info(datasource)

                    if search_for_certain_users and re.search(search_username,connection.username,re.IGNORECASE):

                        connection.server_address = replace_server

                        connection.embed_password = False

                        if overwrite_credentials:

                            connection.embed_password = True

                            connection.username = replace_username

                            connection.password = replace_pw

                            #log.info(connection)

                        server.datasources.update_connection(datasource, connection)

                        x = x + 1

    log.info("Datasource Connections Changed: {}".format(x))

    with server.auth.sign_in(tableau_auth):

        all_workbooks, pagination_item = server.workbooks.get(req_options=request_options)

        log.info("Total Workbooks to Search: {}".format(len(all_workbooks)))

        for wb in all_workbooks:

            server.workbooks.populate_connections(wb)

            for item,conn in enumerate(wb.connections):

                if wb.connections[item].connection_type != 'sqlproxy':

                    if re.search(search_server_regex ,wb.connections[item].server_address,re.IGNORECASE):


                        connection = wb.connections[item]


                        if search_for_certain_users and re.search(search_username, connection.username, re.IGNORECASE):


                            # print(wb.name, '-', connection.connection_type)

                            connection.server_address = replace_server

                            connection.embed_password = False


                            if overwrite_credentials:

                                connection.embed_password = True

                                connection.username = replace_username

                                connection.password = replace_pw


                            server.datasources.update_connection(wb, connection)

                            y = y + 1

    log.info("Workbook Connections Changed: {}".format(y))

    with server.auth.sign_in(tableau_auth):

        all_flows, pagination_item =server.flows.get(req_options=request_options)

        log.info("Total Workbooks to Search: {}".format(len(all_flows)))

        for fl in all_flows:

            server.flows.populate_connections(fl)

            for item,conn in enumerate(fl.connections):

                if re.search(search_server_regex, fl.connections[item].server_address,re.IGNORECASE):

                    connection=fl.connections[item]

                    log.info(fl.name)

                    log.info(fl.project_name)

                    if search_for_certain_users and re.search(search_username, connection.username, re.IGNORECASE):


                        # print(wb.name, '-', connection.connection_type)

                        connection.server_address = replace_server

                        connection.embed_password = False


                        if overwrite_credentials:

                            connection.embed_password = True

                            connection.username = replace_username

                            connection.password = replace_pw


                        server.datasources.update_connection(wb, connection)

                        z = z + 1

    log.info("Flow Connections Changed: {}".format(z))

except Exception as e:

    log.error("Unable to login")

    print("unable to login")



Use the below config file and add your server details.. Copy it to a text document and mention the name and path in the script

Configuration File:

 [server]

search_server : #DB Server

target_server :  #tableau server

overwrite_credentials : True

search_for_certain_users : True

search_username : 

new_pw : 

adminusername: 

adminpw: 

site : #siteid

cert :  #incase you are using SSL cert





Comments