Changing DataSource Password Using WLST (Multiple Domains) - python

I am very new to WLST scripting & currently at beginner level. I have a script which prompts for a password for each datasource it reads. While that part is working fine, the challenge i am facing is that, in production environment, where we want to run this script, there will be multiple managed servers having same datasource with different name but same JNDI as both datasources connecting to same database.
In that scenario the way script is working currently, it will prompt for password for every datasource it finds, but i wanted to modify the script so that it check the JNDIName for datasource & if password was already prompted for any datasource with same JNDI then it should use the same password rather than prompting for password again.
Also there are multi datasources, how can those be handled? Is it possible? besides i am not aware how to get the JNDIName for each datasource. I was trying to get JNDIName as following, which is not working -
jndiName = dataSource.getJNDIName()
This is error i am getting on command line -
Problem invoking WLST - Traceback (innermost last):
File "C:\Script\PostDeploy-DataSourcePasswords.py", line 59, in ?
File "C:\Script\PostDeploy-DataSourcePasswords.py", line 43, in updateJDBCPasswords
AttributeError: getJNDIName
This is the script i am working with -
import sys
#import wlstutility
#wlstutility.initialise(globals())
#from wlstutility import *
#from wlstutility.constructors import *
if len(sys.argv)<1:
print 'Usage: wlst.sh wibble.py <host:port>'
print ' for example: wlst.sh wibble.py prfadmin:14801'
exit()
hostPort = sys.argv[1]
print ('host:port = %s' % hostPort )
connectionUrl = ('t3://%s' % hostPort)
WL_USER='weblogic'
commitChanges=True
WL_PWD=raw_input("Enter Weblogic console password: ")
connect(WL_USER, WL_PWD, connectionUrl)
def updateJDBCPasswords():
PARAMS_TEMPLATE = '/JDBCSystemResources/%s/JDBCResource/%s/JDBCDriverParams/%s'
domainConfig()
# Get JDBC DataSources
cd("JDBCSystemResources")
dataSources = cmo.getJDBCSystemResources()
edit()
# For each DataSource update the password
for dataSource in dataSources :
dsName = dataSource.getName()
print ('DataSource Name : = %s' % dsName)
password=raw_input("Enter database password for " + dsName +" : ")
cd(PARAMS_TEMPLATE % (dsName, dsName, dsName) )
cmo.setPassword(password)
## ===========================================================
# Let's get going
edit()
startEdit()
updateJDBCPasswords()
# dump the changes made so far
print "=== START: The changes that will be applied ==="
showChanges()
if commitChanges :
# =========================================================
# commit the changes
save()
activate(block="true")
else:
# =========================================================
# rollback the changes
print "=== ROLLBACK - cancelling the changes so that they don't get applied ==="
cancelEdit('y')
# =========================================================
# all done - bye!
disconnect()
exit()
Any Help will be much appreciated.
Thanks & Regards,
Amrut Raut.

You try at your test/pre-live environments with simple WLST script that could fetch the JNDI names. You can fetch the JNDI names from the ds below:
cd('/JDBCSystemResource/' + dsName + '/JdbcResource/' + dsName + '/JDBCDataSourceParams/NO_NAME_0')
jarray_jndi_names=get('JNDINames')
jndi_names=[]
for jname in jarray_jndi_names:
jndi_names.append(jname)
Change dsName values with your input or whatever you feel better for your environment.
Once you got the JNDI names you need to use plain if condition to check it already exist then you can use your logic.
keep Note that all multidata sources configured with generic datasources only.
After trying with above hint share your experience.

Related

Python to send a command line to Zebra Designer For Developers

Is there a way that Python can send or in other words, exist a command line that can be send via Python to the " Zebra Designer For Developers Software" to generate the PRN File?
I guess I should add a little bit more context about my question.
I'm working on a software to print labels using NiceLabel Software, the label I need to print is a dynamic label, this means that label information and layout is constantly changing.
I'm able to print the label however if for some reason I need to update the Label Layout a new PRN file needs to be generated, so far I has being do it manually but this is kind of odd since the main reason of my using python is to eliminate the human error
What I'm trying to do is to use Python to generate the PRN file instead users generating the file manually
Please see below a code that we are working on
## Imports
from configparser import ConfigParser
from zebra import Zebra
## Testing Variables
NUM = "128077-00S"
SER_NUM = "3132J908A6"
MODEL = "EM000"
## Get Config File
config = ConfigParser()
config.read('config.ini')
## Set Config Variables
printer = config['printer_setup'].get('printer')
prnFile = config['label_setup'].get('label')
## Read Label File
labelFile = open(prnFile)
label = labelFile.read()
labelFile.close()
## Printing
z = Zebra()
try:
z.getqueues().index(printer)
except ValueError:
print("Printer Not Found: " + printer)
input("\nPress enter to continue...")
else:
z.setqueue(printer)
out = label
out = out.replace("NUM", NUM)
out = out.replace("SER_NUM", SER_NUM)
out = out.replace("MODEL", MODEL)
z.output(out)
print("Label Printed Successfully!")
input("\nPress enter to continue...")
thanks for your help !
As I understand the question, you could replace your first three, or four, "test variables" + config file with argparse usage.
Then you run the script with any arguments you want, such as
python3 app.py -c config.ini --num="128077-00S" --sernum="3132J908A6" --model="EM000"

COM Error while trying to perform action on SAP application

We are using Python pywin32 com library for scripting SAP GUI application running on Windows.
Things were working until yesterday.
Now, while trying to access the line of code below which performs the maximize(), we are getting
com_error: (-2147417851, 'The server threw an exception.', None, None)
And getting the following error while trying to access any object in the SAP window (the last line in code).
AttributeError: Property '.text' cannot be set.
Can someone help? Let me know if more information is needed.
Below is the code snippet which we use to get a new scripting session, launch SAP and perform actions:
from subprocess import call
import win32com.client
import time
GUIPath = 'C:/Program Files (x86)/SAP/FrontEnd/SAPgui/'
WinTitle = 'SAP'
SID = 'xxxxxx.sap.xxxxx.com'
InstanceNo = 'xx'
shell = win32com.client.Dispatch("WScript.Shell")
cmdString = os.path.join(GUIPath, 'SAPgui.exe') + " " + SID + " " + InstanceNo
call(cmdString)
while not shell.AppActivate(WinTitle):
time.sleep(1)
checkGUIExists = False
while not checkGUIExists:
try:
SAP = win32com.client.GetObject("SAPGUI").GetScriptingEngine
session = SAP.FindById("/app/con[0]/ses[0]") # session
checkGUIExists = True
except:
time.sleep(1)
continue
//The lines failing//
session.findById("wnd[0]").maximize()
session.findById("wnd[0]/tbar[0]/okcd).text = <transaction>

WLST execute stored variable "connect()" statement

So, I am passing a environment variable from bash to python;
#!/usr/bin/env python2
import os
#connect("weblogic", "weblogic", url=xxx.xxx.xxx.xxx:xxxx)
os.environ['bash_variable']
via wlst.sh I can print exported bash_variable, but how do I execute stored variable? Basically, I am trying to remove the original connect statement and pass a variable that has said information. Thanks
Question though, why wouldn't you called the script with the variable as an argument and use sys.argv[] ?
By example something like this.
import os
import sys
import traceback
from java.io import *
from java.lang import *
wlDomain = sys.argv[1]
wlDomPath = sys.argv[2]
wlNMHost = sys.argv[3]
wlNMPort = sys.argv[4]
wlDPath="%s/%s" %(wlDomPath,wlDomain)
wlNMprop="/apps/bea/wls/scripts/.shadow/NM.prop"
try:
print "Connection to Node Manager"
print ""
loadProperties(wlNMprop)
nmConnect(username=NMuser,password=NMpass,host=wlNMHost,port=wlNMPort,domainName=wlDomain,domainDir=wlDPath,mType='ssl',verbose='true')
except:
print "Fatal Error : No Connection to Node Manager"
exit()
print "Connected to Node Manager"
The NM.prop file is a 600 file with the username/password for the NM.
EDIT :
So from what I understand you want to do something like this :
URLS = ['t3s://Host1:Port1','t3s://Host2:Port2','t3s://Host3:Port3']
for urls in URLS:
connect('somebody','password',urls)
{bunch of commands}
disconnect()
And the values of the list URLS would be define by the environment.
The way I see it you have 3 choices :
Have 1 script per environment, more or less identical save for the URLS list
Have 1 script but with a conditionnal branching on sys.argv[1] (the environment as a parameter) and create the list there.
Have 1 script which use a parameter file for each environment according to the environment. Each parameter file containing the list in question.
Something like that :
propENV = sys.argv[1]
propPath = "/path1/path2"
propFile = "%s/%s" %(propPath,propENV)
loadProperties(propFile)
I would probably use the properties file option myself as it is more flexible from an operational standpoint...at least IMHO.

ZEO ZODB database - run locally not working

I tried looking at the documentation for running ZEO on a ZODB database, but it isn't working how they say it should.
I can get a regular ZODB running fine, but I would like to make the database accessible by several processes for a program, so I am trying to get ZEO to work.
I created this script in a folder with a subfolder zeo, which will hold the "database.fs" files created by the make_server function in a different parallel process:
CODE:
from ZEO import ClientStorage
import ZODB
import ZODB.config
import os, time, site, subprocess, multiprocessing
# make the server in for the database in a separate process with windows command
def make_server():
runzeo_path = site.getsitepackages()[0] + "\Lib\site-packages\zeo-4.0.0-py2.7.egg\ZEO\\runzeo.py"
filestorage_path = os.getcwd() + '\zeo\database.fs'
subprocess.call(["python", runzeo_path, "-a", "127.0.0.1:9100", "-f" , filestorage_path])
if __name__ == "__main__":
server_process = multiprocessing.Process(target = make_server)
server_process.start()
time.sleep(5)
storage = ClientStorage.ClientStorage(('localhost', 9100), wait=False)
db = ZODB.DB(storage)
connection = db.open()
root = connection.root()
the program will just block at the ClientStorage line if the wait=False is not given.
If the wait=False is given it produces this error:
Error Message:
Traceback (most recent call last):
File "C:\Users\cbrown\Google Drive\EclipseWorkspace\NewSpectro - v1\20131202\2 - database\zeo.py", line 17, in <module>
db = ZODB.DB(storage)
File "C:\Python27\lib\site-packages\zodb-4.0.0-py2.7.egg\ZODB\DB.py", line 443, in __init__
temp_storage.load(z64, '')
File "C:\Python27\lib\site-packages\zeo-4.0.0-py2.7.egg\ZEO\ClientStorage.py", line 841, in load
data, tid = self._server.loadEx(oid)
File "C:\Python27\lib\site-packages\zeo-4.0.0-py2.7.egg\ZEO\ClientStorage.py", line 88, in __getattr__
raise ClientDisconnected()
ClientDisconnected
Here is the output from the cmd prompt for my process which runs a server:
------
2013-12-06T21:07:27 INFO ZEO.runzeo (7460) opening storage '1' using FileStorage
------
2013-12-06T21:07:27 WARNING ZODB.FileStorage Ignoring index for C:\Users\cab0008
\Google Drive\EclipseWorkspace\NewSpectro - v1\20131202\2 - database\zeo\databas
e.fs
------
2013-12-06T21:07:27 INFO ZEO.StorageServer StorageServer created RW with storage
s: 1:RW:C:\Users\cab0008\Google Drive\EclipseWorkspace\NewSpectro - v1\20131202\
2 - database\zeo\database.fs
------
2013-12-06T21:07:27 INFO ZEO.zrpc (7460) listening on ('127.0.0.1', 9100)
What could I be doing wrong? I just want this to work locally right now so there shouldn't be any need for fancy web stuff.
You should use proper process management and simplify your life. You likely want to look into supervisor, which can be responsible for running/starting/stopping your application and ZEO.
Otherwise, you need to look at the double-fork trick to daemonize ZEO -- but why bother when a process management tool like supervisor does this for you.
If you are savvy with relational database administration, and already have a relational database at your disposal -- you can also consider RelStorage as a very good ZODB (low-level) storage backend.
In Windows you should use double \ instead of a single \ in the paths. Easy and portable way to accomplish this is to use os.path.join() function, eg. os.path.join('os.getcwd()', 'zeo', 'database.fs'). Otherwise a similar code worked ok for me.
Had same error on Windows , on Linux everything OK ...
your code is ok , to make this to work change following
C:\Python33\Lib\site-packages\ZEO-4.0.0-py3.3.egg\ZEO\zrpc\trigger.py ln:235
self.trigger.send(b'x')
C:\Python33\Lib\site-packages\ZEO-4.0.0-py3.3.egg\ZEO\zrpc\client.py ln:458:459 - comment them
here is those lines:
if socktype != socket.SOCK_STREAM:
continue

How do i debug my cgi script with mysql database in python. I am new to how to debugg

My code is showing some error when runing on server. i checked the server error log and still not knowing what the exact it mean to say. It says premature end of script.
Now I want to debug my code to check each and every line of code to what does it do ? How am i supose to debugg my code. I am really new to this.
#!/usr/bin/python
import cgitb
import MySQLdb
import cgi
cgitb.enable()
form = cgi.FieldStorage()
f_name = form.getvalue('firstname', '')
l_name = form.getvalue('lastname', '')
age = form.getvalue('age', 0)
gender = form.getvalue('gender', '')
db = MySQLdb.connect("localhost", "root", "gaurav", "Info")
cursor = db.cursor()
sql = "INSERT INTO PERSON (F_Name, L_Name, Age, Gender) VALUES ('%s',' %s',' %d',' %s')" % (f_name, l_name, age, gender)
try:
cursor.execute(sql)
#print "Hello !!"
#print "no of rows inserted: %d " % cursor.rowcount
db.commit()
except:
db.rollback()
db.close()
print "Content-type:text/html"
print "<html>"
print "<h1>DATABASE</h1>"
print "</html>"
The problem is that in HTTP, the headers have to end with a blank line. So, instead of sending one header line and a 3-line body, you're sending four header lines, all but one of which are nonsense, and then exiting without ever finishing the headers.
So, the server complains that the script exited without finished writing the response.
Try this:
print "Content-type:text/html"
print
print "<html>"
print "<h1>DATABASE</h1>"
print "</html>"
If you want to log every line of code, as you said in the comments, there are two ways to do it.
The quick&dirty way is to just open a file and write into it. For example:
#!/usr/bin/python
import cgitb
import MySQLdb
import cgi
with open('/tmp/logfile.log', 'wb') as logfile:
logfile.write('About to enable cgitb\n')
cgitb.enable()
logfile.write('About to create FieldStorage\n')
form = cgi.FieldStorage()
logfile.write('About to get firstname\n')
f_name = form.getvalue('firstname', '')
logfile.write('Firstname is {}. About to get lastname\n'.format(firstname))
l_name = form.getvalue('lastname', '')
logfile.write('Lastname is {}. About to get age\n'.format(lastname))
# and so on
A cleaner way is to use the logging module that comes with Python:
#!/usr/bin/python
import cgitb
import MySQLdb
import cgi
import logging
logging.info('About to enable cgitb')
cgitb.enable()
logging.info('About to create FieldStorage')
form = cgi.FieldStorage()
This is simpler (no need to add \n onto the end, the logger can format strings for you so you don't have to do it manually with .format or %, etc.). And it's a lot more flexible (you can log different messages at different levels, you can configure where the logs go—e.g., send them to your system log instead of a file in /tmp, etc.). And it's more robust (no need to worry about forgetting to close the file and losing the last log messages—note that in the non-logging example, I used a with statement to get the same effect, but that required indenting the whole program).
If you have time to work through the Logging Tutorial, you should do so.
Finally, if you're pretty sure some line is raising an exception, but you can't find the exception information anywhere in the server logs, here's how to log the exception:
import traceback
try:
the line that raises
except Exception:
traceback.print_exc(None, logfile)
raise
This captures the exception, prints out the exact same detailed traceback you would have gotten in a console interpreter session, but into the log file you opened earlier instead of to the console, then lets the exception propagate normally.
If you're using the logging module, you can use its own built-in exception logging, or if you want to customize things you can use sys.exc_info and traceback.format_exception to get a string (or series of strings) to log.
By checking all the possibility of error i found a solution that sequence of import matters here
it should be like
import cgi
import MySQLdb
instead of
import MySQLdb
import cgi

Categories

Resources