Using WebLogic Scripting Tool

Hello,

I got an urgent fix on my open week so we didn't have anything for yesterday. By this event, I will note down my research on using WebLogic Scripting Tool (wlst) for some manipulations on WebLogic (WL) deployment.


Use Case:

I maintain an installation package to WL, at first, we use java API to stop the WL service in order to deploy the loaded packages then start the service again. With the help of wlst, we can deploy it quite simple without caring on the WL service. However, we need to connect to WL server for online methods. I have to read the admin credential to connect into WL server from the boot.properties or config.xml.


Solution:

We can call Python in wlst which also supports Java so called Jython code. So I will use Jython to read the boot.properties file for the admin account to log into WL server. Then use the EncryptionService to decrypt the username and password in this file, many documents about these solutions.

fileObj = open(domainDir + '\\boot.properties')
fileObj.seek(0)
userToken = 'username='
passwordToken = 'password='
encriptedUsr = ''
encriptedPwd = ''
for line in fileObj.readlines():
if userToken in line:
encriptedUsr = line[len(userToken):-1].replace('\\', '')
if passwordToken in line:
encriptedPwd = line[len(passwordToken):-1].replace('\\', '')
fileObj.close()
encryptionService = weblogic.security.internal.SerializedSystemIni.getEncryptionService(domainDir + '\\security')
clearOrEncryptService = weblogic.security.internal.encryption.ClearOrEncryptedService(encryptionService)
if encriptedUsr == '':
domainUsr = 'defaultuser'
else:
domainUsr = clearOrEncryptService.decrypt(encriptedUsr)
if encriptedPwd == '':
domainPwd = 'defaultpassword'
else:
domainPwd = clearOrEncryptService.decrypt(encriptedPwd)

connect(domainUsr, domainPwd, 't3://localhost:7001', timeout=30000)

That's is! However, there are some more things to read:
- Please note: replace('\\', '') for the encrypted data. Seems around 11.1.1.6, WL has added a backslash (somewhere at the end like '\=' instead of '=') in Windows so the decrypt() method will be failed: weblogic.security.internal.encryption.EncryptionServiceException: com.rsa.jsafe.JSAFE_InputException: Invalid input. You remove this backslash then it will be good to go.
- Run wlst tool in console mode for testing, direct to your wlserver under common\bin, call wlst.exe (on Windows) to start the tool.
- Execute a py file, call: execfile('path_to_py_file'). Remember to use forwardslash '/' or double backslash '\\' instead of single backslash '\' in the path.
- Exit wlst: exit()
- My current installation project still has the option to stop WL service so in order to connect to it, I have to start and wait for it runs properly to call the connect(). I have to call this batch command out of the jython script because if I use getRuntime().exec() then it will force an out process to run this execution then the installation process can't control this out process anymore (it will leave a cmd window after finishing)

Batch command:
"sc query your_service | find \"RUNNING\" & if errorlevel 1 sc start your_service & exit"

Jython script:
print ("Checking if WebLogic service is ready ...")
#Runtime.getRuntime().exec("sc query WFO_ProductionDomain_ProductionServer | find \"RUNNING\" & if errorlevel 1 sc start WFO_ProductionDomain_ProductionServer & exit")
bWait = 'true'
response = 0
waitService = 0
waitURL = 0
while bWait == 'true' :
try:
url = URL("http://localhost/url")
uConnection = url.openConnection()
uConnection.connect()
except:
if (waitService > 40):
bWait = 'false'
else:
print "WebLogic service is not ready, wait for 15s ..."
waitService = waitService + 1
sleep(15)
continue
response = uConnection.getResponseCode()
print (response)
uConnection.disconnect()
if ((response == 200) or (waitURL > 40)):
bWait = 'false'
else:
print ("Waiting Weblogic URL for 15s ...")
waitURL = waitURL + 1
sleep(15)

print ("WebLogic is ready!")

- In the first note, with the backslash issue, I though because of the integration with SSO (external authentication provider) that causes the problem, so I read the user data in config.xml as below
from xml.dom import minidom
xmlDoc = minidom.parse(domainDir + '\\config\\config.xml')
authenProvider = xmlDoc.getElementsByTagName('sec:authentication-provider')[0]
if authenProvider.attributes['xsi:type'].value == 'wls:active-directory-authenticatorType':
domainUsr = authenProvider.getElementsByTagName('wls:principal')[0].firstChild.nodeValue
index = domainUsr.find('@')
if index >= 0:
domainUsr = domainUsr[0:index]

encriptedPwd = authenProvider.getElementsByTagName('wls:credential-encrypted')[0].firstChild.nodeValue

This can be another way to retrieve the user data, but it's too complicated for this use case and also too depend on the config.xml format (I have no idea how WL will write this data).

This is for today reading! Nice day all!

Comments