Script for removing IBM Automation foundation from WebSphere Automation operator
The remove-iaf.sh script removes the dependency on both the IBM Automation foundation and IBM Automation foundation core operators from a single instance of the WebSphere Automation 1.5.3 operator. Removing this dependency enables the WebSphere Automation operator to be upgraded to version 1.6.0.
For instructions on using this script, see Removing IBM Automation foundation.
#!/bin/bash
#-------------------------------------------------------------------------------------------------------
# remove-iaf.sh - remove IBM Automation Foundation from a 1.5.3 IBM WebSphere Automation installation
#-------------------------------------------------------------------------------------------------------
#
# This script removes dependency on the IBM Automation Foundation Operator for a "WebSphereAutomation" custom
# resource instance running version 1.5.3 of IBM WebSphere Automation (WSA) Operator, enabling WSA Operator
# upgrades to versions 1.6.0 or higher. It upgrades a single WSA instance only.
#
# This script contains the following optional parameters:
#
# Optional parameters:
# $1 (WSA_OPERATOR_NAMESPACE) - the namespace containing the 1.5.3 IBM WebSphere Automation Operator install
# $2 (WSA_INSTANCE_NAMESPACE) - the namespace containing the "WebSphereAutomation" custom resource instance
#
# Usage:
# 1. arguments - ./remove-iaf.sh <WSA_OPERATOR_NAMESPACE> <WSA_INSTANCE_NAMESPACE>"
# 2. stdin - ./remove-iaf.sh"
#
#-------------------------------------------------------------------------------------------------------
set -o nounset
set -o pipefail
WSA_OPERATOR_NAMESPACE="openshift-operators"
WSA_INSTANCE_NAMESPACE="wasautomation"
SCALE_TO_ZERO_VERSION="1.5.3"
get_csv_name() {
oc get clusterserviceversion -n $WSA_OPERATOR_NAMESPACE -o name | grep "$1\." | cut -d '/' -f2
}
is_greater_than_or_equal_to_scale_to_zero_version() {
semVersion=$(oc get clusterserviceversion -n $WSA_OPERATOR_NAMESPACE -o name | grep "ibm-websphere-automation\." | cut -d '/' -f2 | cut -d 'v' -f2)
IFS='.' read -r -a semVersionArray <<< "$semVersion"
greaterEqualThanScaleToZeroVersion="false"
if [[ "${#semVersionArray[@]}" == "3" ]]; then
IFS='.' read -r -a scaleToZeroVersion <<< "$SCALE_TO_ZERO_VERSION"
if [[ "${semVersionArray[0]}" -gt "${scaleToZeroVersion[0]}" ]]; then
greaterEqualThanScaleToZeroVersion="true"
elif [[ "${semVersionArray[0]}" -eq "${scaleToZeroVersion[0]}" ]]; then
if [[ "${semVersionArray[1]}" -gt "${scaleToZeroVersion[1]}" ]]; then
greaterEqualThanScaleToZeroVersion="true"
elif [[ "${semVersionArray[1]}" -eq "${scaleToZeroVersion[1]}" ]]; then
if [[ "${semVersionArray[2]}" -ge "${scaleToZeroVersion[2]}" ]]; then
greaterEqualThanScaleToZeroVersion="true"
fi
fi
fi
fi
if [[ "$greaterEqualThanScaleToZeroVersion" == "false" ]]; then
echo "You must be on a version greater than $SCALE_TO_ZERO_VERSION to upgrade the WebSphere Automation operator. Exiting."
exit
fi
}
get_subscription_name() {
oc get subscription -n $WSA_OPERATOR_NAMESPACE -o name | grep "$1" | cut -d '/' -f2
}
delete_csv() {
csv_count=$(oc get clusterserviceversion -n $WSA_OPERATOR_NAMESPACE -o name | grep "$1\." -c)
csv=$(get_csv_name "$1")
if [[ "$csv_count" == "1" ]]; then
echo " > Deleting ClusterServiceVersion..."
oc delete clusterserviceversion -n $WSA_OPERATOR_NAMESPACE $csv
elif [[ "$csv_count" == "0" ]]; then
echo " > ClusterServiceVersion not found."
else
echo "Error: Found multiple entries for CSV '$1'. Exiting."
exit 1
fi
}
delete_subscription() {
csv_count=$(oc get subscription -n $WSA_OPERATOR_NAMESPACE -o name | grep "$1" -c)
sub=$(get_subscription_name "$1")
if [[ "$csv_count" == "1" ]]; then
echo " > Deleting Subscription..."
oc delete subscription -n $WSA_OPERATOR_NAMESPACE $sub
elif [[ "$csv_count" == "0" ]]; then
echo " > Subscription not found."
else
echo "Error: Found multiple entries for Subscription '$1'. Exiting."
exit 1
fi
}
delete_operator() {
echo "==> Deleting operator $1"
delete_csv $1
if [[ "$1" == "ibm-automation" ]]; then
delete_subscription "ibm-automation-v"
elif [[ "$WSA_OPERATOR_NAMESPACE" == "openshift-operators" ]]; then
delete_subscription "websphere-automation"
delete_subscription $1
else
delete_subscription $1
fi
}
scale_to_zero() {
scaleToZero=$1
if [[ "$scaleToZero" == "true" ]]; then
oc get websphereautomation -n $WSA_INSTANCE_NAMESPACE -o name | cut -d '/' -f2 | xargs oc patch websphereautomation -n $WSA_INSTANCE_NAMESPACE -p "{\"spec\":{\"scaleToZero\": $scaleToZero}}" --type=merge
else
oc get websphereautomation -n $WSA_INSTANCE_NAMESPACE -o name | cut -d '/' -f2 | xargs oc patch websphereautomation -n $WSA_INSTANCE_NAMESPACE -p "[{ \"op\": \"remove\", \"path\": \"/spec/scaleToZero\" }]" --type=json
fi
}
delete_all() {
resource=$1
echo "==> Deleting all $resource."
oc get $resource -n $WSA_INSTANCE_NAMESPACE -o name | cut -d '/' -f2 | xargs oc delete $resource -n $WSA_INSTANCE_NAMESPACE
}
remove_coupled_fields() {
resource=$1
name=$2
echo "==> Remove coupled fields in $resource $name."
oc patch $resource -n $WSA_INSTANCE_NAMESPACE $name -p "{\"metadata\":{\"ownerReferences\":null}}" --type=merge
oc patch $resource -n $WSA_INSTANCE_NAMESPACE $name -p "{\"metadata\":{\"finalizers\":null}}" --type=merge
oc patch $resource -n $WSA_INSTANCE_NAMESPACE $name -p "{\"metadata\":{\"labels\":{\"app.kubernetes.io/managed-by\":null}}}" --type=merge
sleep 2
check_coupled_fields $resource $name
}
check_coupled_fields() {
resource=$1
name=$2
owner_references_count=$(oc get $resource $name -n $WSA_INSTANCE_NAMESPACE -o jsonpath='{.metadata}' | grep "ownerReferences" -c)
if [[ "$owner_references_count" -ne "0" ]]; then
echo "Could not delete '.metadata.ownerReferences' field in $resource $name. Exiting."
exit 1
fi
managed_by_count=$(oc get $resource $name -n $WSA_INSTANCE_NAMESPACE -o jsonpath='{.metadata.labels}' | grep "app.kubernetes.io/managed-by" -c)
if [[ "$managed_by_count" -ne "0" ]]; then
echo "Could not delete '.metadata.labels["app.kubernetes.io/managed-by"]' field in $resource $name. Exiting."
exit 1
fi
finalizers_count=$(oc get $resource $name -n $WSA_INSTANCE_NAMESPACE -o jsonpath='{.metadata.finalizers}' | grep "\"" -c)
if [[ "$finalizers_count" -ne "0" ]]; then
echo "Could not delete '.metadata.finalizers' field in $resource $name. Exiting."
exit 1
fi
echo " > Successfully updated fields!"
}
wait_for_wsa_ready() {
retries=$1
while true
do
echo "==> Waiting for WebSphere Automation operator to start... ($retries retries)"
alive=$(oc get deployments websphere-automation-operator-controller-manager -n $WSA_OPERATOR_NAMESPACE -o name | grep "deployment.apps" -c)
if [[ "$alive" -eq "1" ]]; then
available_replicas=$(oc get deployments websphere-automation-operator-controller-manager -n $WSA_OPERATOR_NAMESPACE -o=jsonpath="{range .items[*]}{.status.availableReplicas}")
[[ "$available_replicas" -eq "1" ]] && break
fi
((retries-=1))
if (( retries < 0 )); then
echo " > Waited too long for WSA to start. Exiting."
exit 1
fi
sleep 10
done
# Wait 20 seconds for reconcile loop to kick in
sleep 20
retries=$1
while true
do
echo "==> Waiting for WebSphere Automation operator to be ready... ($retries retries)"
# There should only be one WSA instance in a single namespace, so xargs takes one element only
wsa_ready=$(oc get websphereautomation -o name -n $WSA_INSTANCE_NAMESPACE | cut -d '/' -f2 | xargs oc get websphereautomation -n $WSA_INSTANCE_NAMESPACE -o jsonpath='{.status.conditions}' | grep "All prerequisites and installed components are ready" -c)
[[ "$wsa_ready" -eq "1" ]] && break
((retries-=1))
if (( retries < 0 )); then
echo " > Waited too long for WSA to be ready. Exiting."
exit 1
fi
sleep 10
done
}
wait_for_kafka_claim_deleted() {
retries=10
while true
do
echo "==> Waiting for KafkaClaim to be deleted..."
kafka_claim_deleted=$(oc get kafkaclaims -o name -n $WSA_INSTANCE_NAMESPACE | grep "kafkaclaim" -c)
[[ "$kafka_claim_deleted" -eq "0" ]] && break
((retries-=1))
if (( retries < 0 )); then
echo " > Waited too long for KafkaClaims to be deleted. Exiting."
exit 1
fi
sleep 10
done
}
wait_for_kafka_composite_deleted() {
retries=10
while true
do
echo "==> Waiting for KafkaClaim to be deleted..."
kafka_composite_deleted=$(oc get kafkacomposites -o name -n $WSA_INSTANCE_NAMESPACE | grep "kafkacomposite" -c)
[[ "$kafka_composite_deleted" -eq "0" ]] && break
((retries-=1))
if (( retries < 0 )); then
echo " > Waited too long for KafkaComposites to be deleted. Exiting."
exit 1
fi
sleep 10
done
}
get_user_input() {
num_args=$#
if [[ "$num_args" -eq "0" ]]; then
read -p 'WebSphere Automation operator namespace: ' WSA_OPERATOR_NAMESPACE
read -p 'WebSphere Automation instance namespace: ' WSA_INSTANCE_NAMESPACE
elif [[ "$num_args" -eq "2" ]]; then
WSA_OPERATOR_NAMESPACE=$1
WSA_INSTANCE_NAMESPACE=$2
else
echo "Usage:"
echo " 1. arguments - ./remove-iaf.sh <WSA_OPERATOR_NAMESPACE> <WSA_INSTANCE_NAMESPACE>"
echo " 2. stdin - ./remove-iaf.sh"
exit
fi
if [[ -z "$WSA_OPERATOR_NAMESPACE" ]]; then
echo "==> Error: Must set the WebSphere Automation operator's namespace. Exiting."
exit
fi
if [[ -z "$WSA_INSTANCE_NAMESPACE" ]]; then
echo "==> Error: Must set the WebSphere Automation instance's namespace. Exiting."
exit
fi
echo "==> WebSphere Automation operator namespace is set to: $WSA_OPERATOR_NAMESPACE"
echo "==> WebSphere Automation instance namespace is set to: $WSA_INSTANCE_NAMESPACE"
}
validate_user_input() {
# Validate oc login
oc status > /dev/null 2>&1 && true
if [[ $? -ne 0 ]]; then
echo "==> Error: Run 'oc login' to log into a cluster before running remove-iaf.sh. Exiting."
exit 1
fi
# Validate project
wsa_operator_project=$(oc get project $WSA_OPERATOR_NAMESPACE -o name | grep "project.project.openshift.io" -c)
wsa_instance_project=$(oc get project $WSA_INSTANCE_NAMESPACE -o name | grep "project.project.openshift.io" -c)
if [[ "$wsa_operator_project" != "1" ]]; then
echo "==> Error: WebSphere Automation operator namespace does not exist. Not continuing with IBM Automation Foundation removal. Exiting."
exit
fi
if [[ "$wsa_instance_project" != "1" ]]; then
echo "==> Error: WebSphere Automation instance namespace does not exist. Not continuing with IBM Automation Foundation removal. Exiting."
exit
fi
# Validate controller-manager
wsa_operator=$(oc get deployment websphere-automation-operator-controller-manager -n $WSA_OPERATOR_NAMESPACE -o name | grep "deployment.apps" -c)
if [[ "$wsa_operator" != "1" ]]; then
echo "==> Error: WebSphere Automation operator is not installed. Not continuing with IBM Automation Foundation removal. Exiting."
exit
fi
# Validate WSA instance
wsa_instance=$(oc get websphereautomation -n $WSA_INSTANCE_NAMESPACE -o name | grep "websphereautomation.automation.websphere.ibm.com" -c)
if [[ "$wsa_operator" != "1" ]]; then
if [[ "$wsa_operator" == "0" ]]; then
echo "==> Error: There is no WebSphere Automation CR instance in this namespace. Not continuing with IBM Automation Foundation removal. Exiting."
else
echo "==> Error: There must only be one WebSphere Automation CR instance in this namespace. Not continuing with IBM Automation Foundation removal. Exiting."
fi
exit
fi
oc project $WSA_INSTANCE_NAMESPACE
}
# Start here
get_user_input $@
validate_user_input
# Check that scaleToZero feature exists before upgrading
is_greater_than_or_equal_to_scale_to_zero_version
echo ""
echo "==> Starting IBM Automation Foundation removal..."
# Delete IAF core and base
delete_operator "ibm-automation-core"
delete_operator "ibm-automation"
# Scale down WSA, WSS, WSH replicas to 0 (if applicable)
scale_to_zero "true"
wait_for_wsa_ready 50
echo " > Successfully scaled down WebSphere Automation, Health and Secure replicas!"
# Delete WSA Operator and rest of IAF Operators
delete_operator "ibm-websphere-automation"
delete_operator "ibm-automation-eventprocessing"
delete_operator "ibm-automation-flink"
delete_operator "ibm-automation-elastic"
# Backup Kafka cluster (if applicable)
oc get kafkaclaims iaf-system -n $WSA_INSTANCE_NAMESPACE -o name
iaf_kafka_found=$?
if [[ "$iaf_kafka_found" -eq "0" ]]; then
echo "==> Kafka was found. Writing configuration into remove-iaf.sh-kafka.yaml."
oc get kafkas iaf-system -n $WSA_INSTANCE_NAMESPACE -o yaml > remove-iaf.sh-kafka.yaml
# Delete Kafka Claim instances "iaf-system" and "websphereauto-kafka-auth"
oc delete kafkaclaims -n $WSA_INSTANCE_NAMESPACE iaf-system
oc delete kafkaclaims -n $WSA_INSTANCE_NAMESPACE websphereauto-kafka-auth
else
echo "==> Kafka was not found. Continuing with removal."
fi
# Remove ownerReference, managed-by, and finalizer fields (if applicable)
remove_coupled_fields "zenservice" "iaf-zen-cpdservice"
remove_coupled_fields "cartridge" "websphereauto"
remove_coupled_fields "certificate" "iaf-system-automationui-aui-zen-ca"
remove_coupled_fields "certificate" "iaf-system-automationui-aui-zen-cert"
remove_coupled_fields "issuer" "iaf-system-automationui-aui-zen-issuer"
remove_coupled_fields "issuer" "iaf-system-automationui-aui-zen-ss-issuer"
remove_coupled_fields "secret" "external-tls-secret"
# Delete IAF instances
delete_all "cartridges"
delete_all "automationuiconfigs"
delete_all "automationbases"
delete_all "cartridgerequirements"
# Re-apply Kafka cluster
if [[ "$iaf_kafka_found" -eq "0" ]]; then
wait_for_kafka_claim_deleted
wait_for_kafka_composite_deleted
oc apply -f remove-iaf.sh-kafka.yaml -n $WSA_INSTANCE_NAMESPACE
kafka_updated=$?
if [[ "$kafka_updated" -ne "0" ]]; then
echo "==> Could not re-apply backup Kafka cluster from file remove-iaf.sh-kafka.yaml!"
echo " > Manually add the remove-iaf.sh-kafka.yaml file to the cluster before calling remove-iaf.sh again. Exiting."
exit
fi
fi
# Restore WSA, WSS, WSH replicas
scale_to_zero "false"
echo "==> IBM Automation Foundation removal complete!"
echo " Your OpenShift cluster is ready to install IBM WebSphere Automation Operator version >=1.6.0."
echo " To continue this in-place migration, please install the latest driver in the OpenShift UI using OperatorHub."