Skip to main content

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

Popular posts from this blog

Gateway port to use 80 to 443 on Tableau Server

Change Gateway port from 80 to 443 or 8080       To change the Gateway port from 80 to 443 then use below commands First , list your nodes with the command. tsm topology list-node  Then execute the command to set port  tsm topology set-ports --node-name node1 --port-name gateway:primary --port-value 443 The above command will ask for a restart.  Check ports using  tsm topology list-ports  If some error occurs in applying changes: try disabling (enable later) external ssl first- tsm security external-ssl disable You might need to run init command again with new port- tsm reset tabcmd initialuser --server localhost:443 --username 'ADMINUSER' --password 'adminpwd'

Creating Groups using Tableau API and Python Script

 Creating Tableau Groups using Python and API Prerequisites: Python on the machine tableauserverclient module API enabled on Tableau server. Permissions to update for the user Groups.csv file . list all groups in a csv file Changes to be made in the script for below lines in the script groups = open('<Filepath>/groups.csv') pat='getyourpersonaltoken' server = TSC.Server('http://myserver.tableau.com',use_server_version=True) tokenName = 'mytokenname' Script: import tableauserverclient as TSC import csv groups = open('<Filepath>/groups.csv') grp = csv.reader(groups) sourcegroups=[] createdgrps=[] pat='getyourpersonaltoken' server = TSC.Server('http://myserver.tableau.com',use_server_version=True) tokenName = 'mytokenname' ta = TSC.PersonalAccessTokenAuth(token_name=tokenName, personal_access_token=pat) with server.auth.sign_in_with_personal_access_token(ta):    groupslist, pagination_item  = server.groups.get() ...

Tableau dirty Backup

Steps for performing a dirty restore 1. Install Tableau Server 2019.1.0 on the Dev machine 2. Stop Tableau Server 3. Copy the following folders from the current production: D:\Tableau Server\data\tabsvc\pgsql D:\Tableau Server\data\tabsvc\dataengine 4. Update the pg_hba.conf D:\Tableau Server\data\tabsvc\config\pgsql_0.<version>/pg_hba.conf Change "md5" to "trust" for the user "tblwgadmin" like this: host    all         tblwgadmin         <address>/32          md5 to : host    all         tblwgadmin        <address>/32         trust 5. Regenerate the internal token: tsm security regenerate-internal-tokens [options] [global options] tsm pending-changes apply 6. Re-index tsm maintenance reindex-search 7. Make a proper backup: tsm maintenance backup -f myBackup At this point, we w...