Jython renew WebSphere cell default certificate command

certAlias = "default"
newKeyStorePassword = "WebAS"

# Step 1: Generate a new certificate
print "Generating new certificate..."
#AdminTask.createChainedCertificate('-keyStoreName CellDefaultKeyStore -certificateAlias newCertificate -certificateSize 2048 -certificateCommonName localhost -certificateOrganization ibm')
AdminTask.renewCertificate('-keyStoreName CellDefaultKeyStore -certificateAlias default')
# Step 3: Save the configuration
print "Saving the configuration..."
AdminConfig.save()
print "Certificate renewal completed."

run it with command:
 ./wsadmin.sh -lang jython -f renew_certificate.py

Ref: https://www.ibm.com/docs/en/was/8.5.5?topic=tool-personalcertificatecommands-command-group-admintask-object#rxml_atpersonalcert__cmd19

or you can try another script on WAS9

https://www.ibm.com/docs/en/was-nd/9.0.5?topic=tool-personalcertificatecommands-command-group-admintask-object#rxml_atpersonalcert__cmd21

certAlias = "default"
newKeyStorePassword = "new_password"

# Step 1: Generate a new certificate
print "Generating new certificate..."
AdminTask.regenerateKeyAndCertificate('[-alias ' + certAlias + ' -keyStoreName CellDefaultKeyStore -keyStoreScope (cell):' + AdminControl.getCell() + ' -keyStorePassword ' + newKeyStorePassword + ' -keySize 2048 -commonName CN=mycell.mycompany.com -defaultValidityPeriod 365 -renewInDaysBeforeExpiration 30]')

# Step 2: Propagate the new certificate to all nodes
print "Propagating the new certificate..."
AdminTask.propagateKeyRingCertificates('[-keyStoreName CellDefaultKeyStore -keyStoreScope (cell):' + AdminControl.getCell() + ' -keyStorePassword ' + newKeyStorePassword + ']')

# Step 3: Save the configuration
print "Saving the configuration..."
AdminConfig.save()
print "Certificate renewal completed."

python search text in Excel workbook

created the script to search text in whole excel workbook, include all work sheets!

import sys
import openpyxl

wb = openpyxl.load_workbook(sys.argv[1])
worksheets = wb.get_sheet_names()
print(worksheets)
def wordfinder(ws, searchString):
    for i in range(1, ws.max_row + 1):
        for j in range(1, ws.max_column + 1):
            if str(ws.cell(i,j).value).find(searchString) != -1:
                print("found")
                print(ws.cell(i,j))   
                
for sheetname in worksheets:
    ws = wb.get_sheet_by_name(sheetname)
    #print(ws.title)
    wordfinder(ws, sys.argv[2])
C:\>python search_sheets.py hello.xlsx asdfa
['Impacted servers', 'Sheet1']
found
<Cell 'Sheet1'.A1>

python pip full command list

  1. list or check packages
$ pip list
$ pip search pkg
$ pip list --outdated
$ pip show pkg

2. download package

$ pip download --destination-directory /local/wheels -r requirements.txt
$ pip install --no-index --find-links=/local/wheels -r requirements.txt

create wheel file from downloaded package:
$ pip install wheel
$ pip wheel --wheel-dir=/local/wheels -r requirements.txt

3. install packages

install from local:
$ pip install --no-index --find-links=/local/wheels pkg

install with version:
$ pip install pkg>=2.1.2
$ pip install pkg==2.1.2

export installed pkgs and install it:
pip freeze >requirements.txt
pip install -r requirements.txt

4. install with proxy server

$ pip install --proxy [user:passwd@]http_server_ip:port pkg
or you can configure it in $HOME/.config/pip/pip.conf

# Linux/Unix:
/etc/pip.conf
~/.pip/pip.conf
~/.config/pip/pip.conf

# Mac OSX:
~/Library/Application Support/pip/pip.conf
~/.pip/pip.conf
/Library/Application Support/pip/pip.conf

# Windows:
%APPDATA%\pip\pip.ini
%HOME%\pip\pip.ini
C:\Documents and Settings\All Users\Application Data\PyPA\pip\pip.conf (Windows XP)
C:\ProgramData\PyPA\pip\pip.conf

Here is a sample pip.conf:
[global]
index-url = http://mirrors.aliyun.com/pypi/simple/ 

# change to your proxy[user:passwd@]proxy.server:port
proxy=http://xxx.xxx.xxx.xxx:8080 

[install]
trusted-host=mirrors.aliyun.com

5. upgrade and uninstall

$ pip install --upgrade pkg
$ pip install --upgrade pkg1 --upgrade-strategy only-if-need
$ pip uninstall pkg

Listing running applications on running servers using wsadmin scripting

# ------------------------------------------------------
# get line separator
import  java.lang.System  as  sys
lineSeparator = sys.getProperty('line.separator')
cells = AdminConfig.list('Cell').split()
for cell in cells:
    #----------------------------------------------------------------
    # lines 13 and 14 find all the nodes belonging to the cell and
    # process them at a time
    #-----------------------------------------------------------------
    nodes = AdminConfig.list('Node', cell).split()
    for node in nodes:
        #--------------------------------------------------------------
        # lines 19-23 find all the running servers belonging to the cell
        # and node, and process them one at a time
        #--------------------------------------------------------------
        cname = AdminConfig.showAttribute(cell, 'name')
        nname = AdminConfig.showAttribute(node, 'name')
        servs = AdminControl.queryNames('type=Server,cell=' + cname + ',node=' + nname + ',*').split()
        print "Number of running servers on node " + nname + ": %s \n" %(len(servs))
        for server in servs:
            #---------------------------------------------------------
            #lines 28-34 get some attributes from the server to display;
            # invoke an operation on the server JVM to display a property.
            #---------------------------------------------------------
            sname = AdminControl.getAttribute(server, 'name')
            ptype = AdminControl.getAttribute(server, 'processType')
            pid   = AdminControl.getAttribute(server, 'pid')
            state = AdminControl.getAttribute(server, 'state')
            jvm = AdminControl.queryNames('type=JVM,cell=' + cname + ',node=' + nname + ',process=' + sname + ',*')
            osname = AdminControl.invoke(jvm, 'getProperty', 'os.name')
            print " " + sname + " " +  ptype + " has pid " + pid + ";state: " + state + "; on " + osname + "\n"
    
            #---------------------------------------------------------
            # line 40-45 find the applications running on this server and
            # display the application name.
            #---------------------------------------------------------
            apps = AdminControl.queryNames('type=Application,cell=' + cname + ',node=' + nname + ',process=' + sname + ',*').splitlines()
            print "Number of applications running on " + sname + ": %s \n"% (len(apps))
            for app in apps:
                aname = AdminControl.getAttribute(app, 'name')
                print aname + "\n"
                print "----------------------------------------------------"
                print "\n"

jython script to add Generic JVM arguments for Log4j Security Vulnerabilities fix

$ ./wsadmin.sh -lang jython -f addJVMArg_new.py server1 add "-Dlog4j2_formatMsgNoLookups=true"
WASX7209I: Connected to process "server1" on node AppNode01 using SOAP connector;  The type of process is: UnManagedProcess
WASX7303I: The following options are passed to the scripting environment and are available as arguments that are stored in the argv variable: "[server1, add, -Dlog4j2_formatMsgNoLookups=true]"
JVM Name is :  server1
Action is :  add
JVM ID is (cells/Cell01/nodes/AppNode01/servers/server1|server.xml#JavaVirtualMachine_1183122130078)
JVM Arguments are : -Xcomp -XX:-TieredCompilation
new_argument is :  -Dlog4j2_formatMsgNoLookups=true
-Xcomp -XX:-TieredCompilation
Need to add the arguments
modified arguments is as below :
-Xcomp -XX:-TieredCompilation -Dlog4j2_formatMsgNoLookups=true
### addJVMArg_new.py ###
import os
import sys
import java
import java.util as util
import java.io as javaio

def usage():
 print "./wsadmin.sh -lang jython -f addJVMArg_new.py <JVM_name> add <New_argument>"
 print "./wsadmin.sh -lang jython -f addJVMArg_new.py <JVM_name> update"
 
 
def getJVMConfigID(jvm_name):
 server_list=AdminConfig.list('Server').splitlines()
 for server in server_list:
  server_name=AdminConfig.showAttribute(server,'name')
  if (server_name==jvm_name):
   jvm_id=AdminConfig.list('JavaVirtualMachine',server)
   return jvm_id
   
def currentJvmArguments(jvm_id):
 #print "Current JVM arguments"
 current_arguments=AdminConfig.showAttribute(jvm_id,"genericJvmArguments")
 #print str(current_arguments)
 return str(current_arguments)
   
def updateJvmArguments(jvm_id):
 current_arguments=currentJvmArguments(jvm_id)
 print str(current_arguments)
 print "Input new arguments"
 new_arguments=raw_input("Provide the new arguments :")
 print new_arguments
 print AdminConfig.modify(jvm_id,[['genericJvmArguments',new_arguments]])
 print AdminConfig.save()
 

def addJvmArguments(jvm_id,action,new_argument):
 current_arguments=currentJvmArguments(jvm_id)
 print str(current_arguments)
 print "Need to add the arguments"
 current_arguments=str(current_arguments) + ' ' + new_argument
 print "modified arguments is as below :"
 print current_arguments
 print AdminConfig.modify(jvm_id,[['genericJvmArguments',current_arguments]])
 print AdminConfig.save()
 
   
if not (len(sys.argv) >= 2):
 print "Usage : ",
 usage()
 sys.exit(1)
 
 
 
#######################################################################
######################## Main script ##################################
#######################################################################

jvm_name=sys.argv[0]
action=sys.argv[1]

print "JVM Name is : ", jvm_name
print "Action is : ", action
#print "new_argument is : ", new_argument

# Retrieve the JVM Config id

jvm_id=getJVMConfigID(jvm_name)
jvm_arguments=currentJvmArguments(jvm_id)

print "JVM ID is", jvm_id
print "JVM Arguments are :", jvm_arguments

if (action == "add"):
 new_argument=sys.argv[2]
 print "new_argument is : ", new_argument
 addJvmArguments(jvm_id,action,new_argument)
else:
 updateJvmArguments(jvm_id)

### END of Main Script

ansible playbook checkIfAppExists then undeploy/deploy in Azure pipeline

we can use this playbook.yml file to checkIfAppExists:

---
- hosts: all
  become: wasadmin
  tasks:
    - name: Register a variable
      ansible.builtin.shell: /app/IBM/WebSphere/AppServer/profiles/AppSrv01/bin/wsadmin.sh -conntype none -lang jython -c 'AdminApplication.checkIfAppExists("PlantsByWebSphere")'
      register: checkIfAppExists_out
    - debug: var=checkIfAppExists_out.stdout_lines
    - name: undeploy
      ansible.builtin.command: /app/IBM/WebSphere/AppServer/profiles/AppSrv01/bin/wsadmin.sh -conntype none -lang jython -c "AdminApp.uninstall('PlantsByWebSphere')"
      when: not "false" in checkIfAppExists_out.stdout
    - name: deploy war file
      ansible.builtin.command: /app/IBM/WebSphere/AppServer/profiles/AppSrv01/bin/wsadmin.sh -conntype none -lang jython -c "AdminApp.install('/home/vadmin/jsat-API-{{env_name}}-1.0.0.war', ['-appname', 'PlantsByWebSphere', '-usedefaultbindings', '-server', 'server1'])"
    - name: start the application
      ansible.builtin.command: /app/IBM/WebSphere/AppServer/profiles/AppSrv01/bin/wsadmin.sh -lang jython -c "AdminApplication.startApplicationOnSingleServer('PlantsByWebSphere', 'AppNode01', 'server1')"

Here is the output from pipeline:

2021-12-15T15:14:52.3811853Z PLAY [all] *********************************************************************
2021-12-15T15:14:52.3903924Z 
2021-12-15T15:14:52.3904885Z TASK [Gathering Facts] *********************************************************
2021-12-15T15:14:55.6895107Z ok: [10.200.14.87]
2021-12-15T15:14:55.7094046Z 
2021-12-15T15:14:55.7102411Z TASK [Register a variable] *****************************************************
2021-12-15T15:15:00.6996473Z changed: [10.200.14.87]
2021-12-15T15:15:00.7187784Z 
2021-12-15T15:15:00.7189161Z TASK [debug] *******************************************************************
2021-12-15T15:15:00.7670493Z ok: [10.200.14.87] => {
2021-12-15T15:15:00.7671874Z     "checkIfAppExists_out.stdout_lines": [
2021-12-15T15:15:00.7672744Z         "WASX7357I: By request, this scripting client is not connected to any server process. Certain configuration and application operations will be available in local mode.", 
2021-12-15T15:15:00.7674211Z         "---------------------------------------------------------------", 
2021-12-15T15:15:00.7674861Z         " AdminApplication:       Check if application exists", 
2021-12-15T15:15:00.7675503Z         " Application Name:       PlantsByWebSphere", 
2021-12-15T15:15:00.7676093Z         " Usage: AdminApplication.checkIfAppExists(\"PlantsByWebSphere\")", 
2021-12-15T15:15:00.7676828Z         " Return: Checks whether the application exists. If the application exists, a true value is returned.", 
2021-12-15T15:15:00.7677784Z         "---------------------------------------------------------------", 
2021-12-15T15:15:00.7678312Z         " ", 
2021-12-15T15:15:00.7679286Z         " ", 
2021-12-15T15:15:00.7679870Z         "'false'"
2021-12-15T15:15:00.7680488Z     ]
2021-12-15T15:15:00.7681033Z }
2021-12-15T15:15:00.7849801Z 
2021-12-15T15:15:00.7851020Z TASK [undeploy] ****************************************************************
2021-12-15T15:15:00.8276416Z skipping: [10.200.14.87]
2021-12-15T15:15:00.8464468Z 
2021-12-15T15:15:00.8467003Z TASK [deploy war file] *********************************************************
2021-12-15T15:15:29.0518902Z changed: [10.200.14.87]
2021-12-15T15:15:29.0530467Z 
2021-12-15T15:15:29.0531564Z PLAY RECAP *********************************************************************
2021-12-15T15:15:29.0532228Z 10.200.14.87               : ok=4    changed=2    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   

WebSphere jacl script list JVM ports

set cells [$AdminConfig list Cell]
foreach cell $cells {
    set cname [$AdminConfig showAttribute $cell name]
    set nodes [$AdminConfig list Node $cell]
    foreach node $nodes {
        set nname [$AdminConfig showAttribute $node name]
        puts "$nname"
        set serverEntries [$AdminConfig list ServerEntry $node]
        foreach serverEntry $serverEntries {
            set sname [$AdminConfig showAttribute $serverEntry serverName]
            puts "$sname port listed as below:"
            puts "#######################################################"
            set namedEndPoints [$AdminConfig list NamedEndPoint $serverEntry]
            foreach namedEndPoint $namedEndPoints {
                set endPointName [$AdminConfig showAttribute $namedEndPoint "endPointName"]
                set endPoint [$AdminConfig showAttribute $namedEndPoint "endPoint"]
                set host [$AdminConfig showAttribute $endPoint "host"]
                set port [$AdminConfig showAttribute $endPoint "port"]
                puts "$endPointName: $host:$port"

}}}}
 $ ./wsadmin.sh -f list.jacl
WASX7209I: Connected to process "server1" on node AppNode01 using SOAP connector;  The type of process is: UnManagedProcess
AppNode01
server1 port listed as below:
#######################################################
BOOTSTRAP_ADDRESS: labvm:2809
SOAP_CONNECTOR_ADDRESS: labvm:8880
ORB_LISTENER_ADDRESS: labvm:9100
SAS_SSL_SERVERAUTH_LISTENER_ADDRESS: labvm:9401
CSIV2_SSL_SERVERAUTH_LISTENER_ADDRESS: labvm:9403
CSIV2_SSL_MUTUALAUTH_LISTENER_ADDRESS: labvm:9402
WC_adminhost: *:9060
WC_defaulthost: *:9080
DCS_UNICAST_ADDRESS: *:9353
WC_adminhost_secure: *:9043
WC_defaulthost_secure: *:9443
SIP_DEFAULTHOST: *:5060
SIP_DEFAULTHOST_SECURE: *:5061
SIB_ENDPOINT_ADDRESS: *:7276
SIB_ENDPOINT_SECURE_ADDRESS: *:7286
SIB_MQ_ENDPOINT_ADDRESS: *:5558
SIB_MQ_ENDPOINT_SECURE_ADDRESS: *:5578
IPC_CONNECTOR_ADDRESS: ${LOCALHOST_NAME}:9633
OVERLAY_UDP_LISTENER_ADDRESS: *:11003
OVERLAY_TCP_LISTENER_ADDRESS: *:11004

List WebSphere applications deployed on each JVM

Run this command to list applications deployed on each JVM:
./wsadmin.sh -f listapps.jacl

set cells [$AdminConfig list Cell]
foreach cell $cells {
    set cname [$AdminConfig showAttribute $cell name]
    set nodes [$AdminConfig list Node $cell]
    foreach node $nodes {
        set nname [$AdminConfig showAttribute $node name]
        puts "$nname"
        set serverEntries [$AdminConfig list ServerEntry $node]
        foreach serverEntry $serverEntries {
            set sname [$AdminConfig showAttribute $serverEntry serverName]
            puts "Applications installed on $sname listed as below:"
            puts "#######################################################"
            set appname [$AdminApp list WebSphere:cell=$cname,node=$nname,server=$sname]
            puts "$appname"
}}}

Create a java project and compile with Azure pipeline

STEP 1. Create a java project with maven

mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false

STEP 2. Upload created my-app to GIT or Azure repo

STEP 3. Create my-app.yml as pipeline

# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more: this is dummy commit
# https://aka.ms/yaml

trigger:
- main

pool:
  vmImage: 'ubuntu-latest'

steps:
- script: echo Hello, world!
  displayName: 'Run a one-line script'

- script: |
    echo Add other tasks to build, test, and deploy your project.
    echo See https://aka.ms/yaml
  displayName: 'Run a multi-line script'

- task: Maven@3
  inputs:
    mavenPomFile: 'my-app/pom.xml' 

- publish: $(System.DefaultWorkingDirectory)
  artifact: 'my-app-1.0-SNAPSHOT.jar'


- task: DownloadPipelineArtifact@2
  inputs:
    buildType: current
    artifact: 'my-app-1.0-SNAPSHOT.jar'


STEP 4. Run the pipeline and check the my-app-1.0-SNAPSHOT.jar

Jython Script to create MINE web data-source and JDBC provider

# Jython Script to create MINE web data-source and JDBC provider. 
#

#Import Statements
import os
import re
import sys

# Create JDBC provider for MINE oracle database.
def createMINEJDBCProvider():
    server = '/Server:server1'
    # Set the Node ID
    serverID = AdminConfig.getid(server)
    print 'Server ID:' + serverID

    #Configuring J2c auth
    userAlias='test/MINEDBUser'
    alias = ['alias', userAlias]
    userid = ['userId', 'MINEDB']
    password = ['password', 'MINEpass']
    jaasAttrs = [alias, userid, password]
    security = AdminConfig.getid('/Security:/')
    print 'security:'+security
    j2cUser=AdminConfig.create('JAASAuthData', security, jaasAttrs)
    AdminConfig.save()
    print 'Creating MINE User sucessfull'

    # Test to see if the provider has already been created.
    MINEJDBCprovider = AdminConfig.getid('/JDBCProvider:Oracle JDBC Driver/')
    if len(MINEJDBCprovider) == 0:
        providerName='Oracle JDBC Driver'
        print 'creating Oracle JDBC provider on server:'+serverID
        print 'JDBC provider Name:'+providerName
        MINEJDBCprop1 = ['name', providerName]
        MINEJDBCprop2 = ['description','Oracle JDBC Driver for MINE Application']
        MINEJDBCprop3 = ['implementationClassName','oracle.jdbc.pool.OracleConnectionPoolDataSource']
        MINEJDBCprop4 = ['classpath','${ORACLE_JDBC_DRIVER_PATH}/ojdbc6.jar']
        MINEJDBCprops=[MINEJDBCprop1,MINEJDBCprop2,MINEJDBCprop3,MINEJDBCprop4]
        providerID = AdminConfig.create('JDBCProvider', serverID, MINEJDBCprops)
        AdminConfig.save()
        print 'Creating Oracle JDBC provider on server sucessfull with provider:'+providerID
        createMINEDataSource()
    else:
        print 'oracle provider exists:'+MINEJDBCprovider


def createMINEDataSource():
    providerName='Oracle JDBC Driver'
    userAlias='test/MINEDBUser'
    MINEJDBCprovider = AdminConfig.getid('/JDBCProvider:Oracle JDBC Driver/')
    MINEDataSource = AdminConfig.getid('/JDBCProvider:'+providerName+'/DataSource:MINEDB/')
    if len(MINEDataSource) == 0:
        # Set the datasource attributes
            MINEDSprop1 = ['name', 'MINEDB']
            MINEDSprop2 = ['jndiName', 'jdbc/MINEdb']
            MINEDSprop3 = ['description', 'MINE database']
            MINEDSprop4 = ['datasourceHelperClassname', 'com.ibm.websphere.rsadapter.Oracle11gDataStoreHelper']
            MINEDSprop5 = ['authDataAlias' , userAlias]
            mapConfigprop=["mappingConfigAlias", "DefaultPrincipalMapping"] 
            mapConfigs=[MINEDSprop5 , mapConfigprop] 
            mappingConfig=["mapping", mapConfigs]

            MINEDSprops = [MINEDSprop1, MINEDSprop2, MINEDSprop3, MINEDSprop4, MINEDSprop5, mappingConfig]
            MINEDataSource = AdminConfig.create('DataSource', MINEJDBCprovider, MINEDSprops)

            #Set the DB URL
            propSet = AdminConfig.create('J2EEResourcePropertySet', MINEDataSource, [])
            AdminConfig.create('J2EEResourceProperty', propSet, [["name", "URL"], ["value", "jdbc:oracle:thin:@myserver:1523:MINED2"]])

            AdminConfig.save()
            print 'Creating MINE JDBC Datasource on server sucessfull with datasource:'+MINEDataSource

    else:
        print 'MINE Datasource already exists in the server:'+MINEDataSource
        print 'Testing datasource connection'
        print AdminControl.testConnection(MINEDataSource)

try:

    print 'start'
    createMINEJDBCProvider()
    createMINEDataSource()
    print 'end'
except:
    print "***** Unexpected error while creating JDBC datasource:", sys.exc_info(), " *****"
    raise