diff --git a/kubernetes/samples/scripts/common/utility.sh b/kubernetes/samples/scripts/common/utility.sh index 1144a31fc30..500e71fb1b3 100644 --- a/kubernetes/samples/scripts/common/utility.sh +++ b/kubernetes/samples/scripts/common/utility.sh @@ -185,6 +185,23 @@ function checkPvState { fi } +# +# Check the state of a persistent volume claim. +# $1 - name of volume claim +# $2 - expected state of volume claim +function checkPvcState { + echo "Checking if the persistent volume claim ${1:?} is ${2:?}" + local end_secs=$((SECONDS + 30)) + local pvc_state=`kubectl get pvc $1 -o jsonpath='{.status.phase}'` + while [ ! "$pvc_state" = "$2" ] && [ $SECONDS -le $end_secs ]; do + sleep 1 + pvc_state=`kubectl get pvc $1 -o jsonpath='{.status.phase}'` + done + if [ "$pvc_state" != "$2" ]; then + fail "The persistent volume state should be $2 but is $pvc_state" + fi +} + # # Function to check if a persistent volume exists # $1 - name of volume diff --git a/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/azure-csi-storageaccount-template.yaml b/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/azure-csi-storageaccount-template.yaml new file mode 100644 index 00000000000..004d6c89896 --- /dev/null +++ b/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/azure-csi-storageaccount-template.yaml @@ -0,0 +1,16 @@ +# Copyright (c) 2018, 2021, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: %STORAGE_CLASS_NAME% +provisioner: file.csi.azure.com +parameters: + protocol: nfs + resourceGroup: %STORAGE_ACCOUNT_RESOURCE_GROUP_NAME% + storageAccount: %STORAGE_ACCOUNT_NAME% + shareName: %AZURE_FILE_SHARE_NAME% +reclaimPolicy: Delete +volumeBindingMode: Immediate +allowVolumeExpansion: true \ No newline at end of file diff --git a/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/azure-file-pv-template.yaml b/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/azure-file-pv-template.yaml deleted file mode 100644 index db1b5dbcf98..00000000000 --- a/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/azure-file-pv-template.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (c) 2018, 2021, Oracle and/or its affiliates. -# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. - -apiVersion: v1 -kind: PersistentVolume -metadata: - name: %PERSISTENT_VOLUME_NAME% - labels: - usage: %PERSISTENT_VOLUME_NAME% -spec: - capacity: - storage: 10Gi - accessModes: - - ReadWriteMany - storageClassName: %STORAGE_CLASS_NAME% - persistentVolumeReclaimPolicy: Retain - azureFile: - secretName: %AZURE_FILE_SHARE_SECRET_NAME% - shareName: %AZURE_FILE_SHARE_NAME% - readOnly: false - mountOptions: - - dir_mode=0777 - - file_mode=0777 - - uid=1000 - - gid=1000 - - mfsymlinks - - nobrl diff --git a/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/azure-file-pvc-template.yaml b/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/azure-file-pvc-template.yaml index 75d79d4f5e4..cd5aa6866a3 100644 --- a/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/azure-file-pvc-template.yaml +++ b/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/azure-file-pvc-template.yaml @@ -11,7 +11,4 @@ spec: storageClassName: %STORAGE_CLASS_NAME% resources: requests: - storage: 10Gi - selector: - matchLabels: - usage: %PERSISTENT_VOLUME_CLAIM_NAME% + storage: 100Gi diff --git a/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/create-domain-on-aks-inputs.yaml b/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/create-domain-on-aks-inputs.yaml index f97777e99c2..1ec8bfd7be1 100644 --- a/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/create-domain-on-aks-inputs.yaml +++ b/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/create-domain-on-aks-inputs.yaml @@ -53,17 +53,6 @@ azureKubernetesNodeVMSize: Standard_DS2_v2 # The suffix of azure kubernetes node pool name, the azure kubernetes node pool name will be${azureKubernetesNodepoolNamePrefix} ${namePrefix}. azureKubernetesNodepoolNamePrefix: pool1 -# SKU of azure storage account, used to create storage account. -azureStorageAccountSku: Standard_LRS - -# Name of Azure Storage Class. We will use initial StorageClasses azurefile. -# If you want to create new class, follow the document: https://docs.microsoft.com/en-us/azure/aks/azure-files-dynamic-pv#create-a-storage-class. -# Go to this page for more details: https://docs.microsoft.com/en-us/azure/aks/concepts-storage#storage-classes -azureStorageClassName: azurefile - -# The suffix of azure storage file share name, the complete value is ${namePrefix}-${azureStorageShareNameSuffix}-, used to create file share, and mount file share. -azureStorageShareNameSuffix: weblogic - #Java Option for WebLogic Server javaOptions: -Dweblogic.StdoutDebugEnabled=false -XX:MinRAMPercentage=25.0 -XX:MaxRAMPercentage=50.0 @@ -72,6 +61,12 @@ javaOptions: -Dweblogic.StdoutDebugEnabled=false -XX:MinRAMPercentage=25.0 -XX:M # Parameter "imagePullSecretName" will be overwritten with this field in kubernetes/samples/scripts/create-weblogic-domain/domain-home-on-pv/create-domain-inputs.yaml imagePullSecretNameSuffix: regcred +# Storage class name for Azure Files using Container Storage Interface driver, see https://docs.microsoft.com/en-us/azure/aks/azure-files-csi#nfs-file-shares +azureFileCsiNfsClassName: azurefile-csi-nfs + +# The suffix of azure storage file share name, the complete value is ${namePrefix}-${azureStorageShareNameSuffix}-, used to create file share, and mount file share. +azureStorageShareNameSuffix: weblogic + # Resource request for each server pod (Memory and CPU). This is minimum amount of compute # resources required for each server pod. Edit value(s) below as per pod sizing requirements. # These are optional diff --git a/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/create-domain-on-aks.sh b/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/create-domain-on-aks.sh index 79fa7c11a0c..b9acf0b7c57 100755 --- a/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/create-domain-on-aks.sh +++ b/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/create-domain-on-aks.sh @@ -3,10 +3,10 @@ # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. # # Description -# This sample script creates a WebLogic Server domain home on the Azure Kubernetes Service (AKS). -# It creates a new Azure resource group, with a new Azure Storage Account and Azure File Share to allow WebLogic +# This sample script creates a WebLogic Server domain home on the Azure Kubernetes Service (AKS). +# It creates a new Azure resource group, with a new Azure Storage Account and Azure File Share to allow WebLogic # to persist its configuration and data separately from the Kubernetes pods that run WebLogic workloads. -# Besides, it also generates the domain resource yaml files, which can be used to restart the Kubernetes +# Besides, it also generates the domain resource yaml files, which can be used to restart the Kubernetes # artifacts of the corresponding domain. # # The Azure resource deployment is customized by editing @@ -24,7 +24,7 @@ # Initialize script="${BASH_SOURCE[0]}" -scriptDir="$( cd "$( dirname "${script}" )" && pwd )" +scriptDir="$(cd "$(dirname "${script}")" && pwd)" source ${scriptDir}/../common/utility.sh source ${scriptDir}/../common/validate.sh @@ -46,19 +46,26 @@ function usage { executeIt=false while getopts "ehi:o:u:d:" opt; do case $opt in - i) valuesInputFile="${OPTARG}" + i) + valuesInputFile="${OPTARG}" ;; - o) outputDir="${OPTARG}" + o) + outputDir="${OPTARG}" ;; - u) azureResourceUID="${OPTARG}" + u) + azureResourceUID="${OPTARG}" ;; - e) executeIt=true + e) + executeIt=true ;; - d) domainInputFile="${OPTARG}" + d) + domainInputFile="${OPTARG}" ;; - h) usage 0 + h) + usage 0 ;; - *) usage 1 + *) + usage 1 ;; esac done @@ -77,8 +84,8 @@ if [ "${missingRequiredOption}" == "true" ]; then usage 1 fi -if [ -z "${azureResourceUID}" ];then - azureResourceUID=`date +%s` +if [ -z "${azureResourceUID}" ]; then + azureResourceUID=$(date +%s) fi # @@ -96,13 +103,13 @@ function fail { function initOutputDir { aksOutputDir="$outputDir/weblogic-on-aks" - pvOutput="${aksOutputDir}/pv.yaml" + scOutput="${aksOutputDir}/azure-csi-nfs.yaml" pvcOutput="${aksOutputDir}/pvc.yaml" adminLbOutput="${aksOutputDir}/admin-lb.yaml" clusterLbOutput="${aksOutputDir}/cluster-lb.yaml" domain1Output="${aksOutputDir}/domain1.yaml" - removeFileIfExists ${pvOutput} + removeFileIfExists ${scOutput} removeFileIfExists ${pvcOutput} removeFileIfExists ${adminLbOutput} removeFileIfExists ${clusterLbOutput} @@ -130,9 +137,9 @@ function initialize { validationError "You must use the -o option to specify the name of an existing directory to store the generated yaml files in." fi - domainPVInput="${scriptDir}/azure-file-pv-template.yaml" - if [ ! -f ${domainPVInput} ]; then - validationError "The template file ${domainPVInput} for generating a persistent volume was not found" + storageClassInput="${scriptDir}/azure-csi-storageaccount-template.yaml" + if [ ! -f ${storageClassInput} ]; then + validationError "The template file ${storageClassInput} for generating a NFS storage class was not found" fi domainPVCInput="${scriptDir}/azure-file-pvc-template.yaml" @@ -166,7 +173,7 @@ function initialize { export azureStorageShareName="${namePrefix}-${azureStorageShareNameSuffix}-${azureResourceUID}" export imagePullSecretName="${namePrefix}${imagePullSecretNameSuffix}" export persistentVolumeClaimName="${namePrefix}-${persistentVolumeClaimNameSuffix}-${azureResourceUID}" - + export persistentVolumeId="${namePrefix}-${persistentVolumeClaimNameSuffix}-${azureResourceUID}" } # @@ -184,20 +191,20 @@ function createYamlFiles { # (if needed) and copy the inputs file there. copyInputsFileToOutputDirectory ${valuesInputFile} "${aksOutputDir}/create-domain-on-aks-inputs.yaml" - echo Generating ${pvOutput} + echo Generating ${scOutput} - cp ${domainPVInput} ${pvOutput} - sed -i -e "s:%PERSISTENT_VOLUME_NAME%:${persistentVolumeClaimName}:g" ${pvOutput} - sed -i -e "s:%AZURE_FILE_SHARE_SECRET_NAME%:${azureFileShareSecretName}:g" ${pvOutput} - sed -i -e "s:%AZURE_FILE_SHARE_NAME%:${azureStorageShareName}:g" ${pvOutput} - sed -i -e "s:%STORAGE_CLASS_NAME%:${azureStorageClassName}:g" ${pvOutput} + cp ${storageClassInput} ${scOutput} + sed -i -e "s:%STORAGE_CLASS_NAME%:${azureFileCsiNfsClassName}:g" ${scOutput} + sed -i -e "s:%AZURE_FILE_SHARE_NAME%:${azureStorageShareName}:g" ${scOutput} + sed -i -e "s:%STORAGE_ACCOUNT_RESOURCE_GROUP_NAME%:${azureResourceGroupName}:g" ${scOutput} + sed -i -e "s:%STORAGE_ACCOUNT_NAME%:${storageAccountName}:g" ${scOutput} # Generate the yaml to create the persistent volume claim echo Generating ${pvcOutput} cp ${domainPVCInput} ${pvcOutput} sed -i -e "s:%PERSISTENT_VOLUME_CLAIM_NAME%:${persistentVolumeClaimName}:g" ${pvcOutput} - sed -i -e "s:%STORAGE_CLASS_NAME%:${azureStorageClassName}:g" ${pvcOutput} + sed -i -e "s:%STORAGE_CLASS_NAME%:${azureFileCsiNfsClassName}:g" ${pvcOutput} # Generate the yaml to create WebLogic Server domain. echo Generating ${domain1Output} @@ -234,11 +241,11 @@ function createYamlFiles { # javaOptions may contain tokens that are not allowed in export command # we need to handle it differently. # we set the javaOptions variable that can be used later - tmpStr=`grep "javaOptions" ${exportValuesFile}` + tmpStr=$(grep "javaOptions" ${exportValuesFile}) javaOptions=${tmpStr//"javaOptions="/} # We exclude javaOptions from the exportValuesFile - grep -v "javaOptions" ${exportValuesFile} > ${tmpFile} + grep -v "javaOptions" ${exportValuesFile} >${tmpFile} source ${tmpFile} rm ${exportValuesFile} ${tmpFile} @@ -265,142 +272,164 @@ function createYamlFiles { } function loginAzure { - # login with a service principal - az login --service-principal --username $azureServicePrincipalAppId \ - --password $azureServicePrincipalClientSecret \ - --tenant $azureServicePrincipalTenantId - echo Login Azure with Servie Principal successfully. - - if [ $? -ne 0 ]; then - fail "Login to Azure failed!" - fi + # login with a service principal + az login --service-principal --username $azureServicePrincipalAppId \ + --password $azureServicePrincipalClientSecret \ + --tenant $azureServicePrincipalTenantId + echo Login Azure with Servie Principal successfully. + + if [ $? -ne 0 ]; then + fail "Login to Azure failed!" + fi } function createResourceGroup { - # Create a resource group - echo Check if ${azureResourceGroupName} exists - ret=$(az group exists --name ${azureResourceGroupName}) - if [ $ret != false ];then - fail "${azureResourceGroupName} exists, please change value of namePrefix to generate a new resource group name." - fi + # Create a resource group + echo Check if ${azureResourceGroupName} exists + ret=$(az group exists --name ${azureResourceGroupName}) + if [ $ret != false ]; then + fail "${azureResourceGroupName} exists, please change value of namePrefix to generate a new resource group name." + fi - echo Creating Resource Group ${azureResourceGroupName} - az group create --name $azureResourceGroupName --location $azureLocation + echo Creating Resource Group ${azureResourceGroupName} + az group create --name $azureResourceGroupName --location $azureLocation } function createAndConnectToAKSCluster { - # Create aks cluster - echo Check if ${aksClusterName} exists - ret=$(az aks list -g ${azureResourceGroupName} | grep "${aksClusterName}") - if [ -n "$ret" ];then - fail "AKS instance with name ${aksClusterName} exists." - fi + # Create aks cluster + echo Check if ${aksClusterName} exists + ret=$(az aks list -g ${azureResourceGroupName} | grep "${aksClusterName}") + if [ -n "$ret" ]; then + fail "AKS instance with name ${aksClusterName} exists." + fi - echo Creating Azure Kubernetes Service ${aksClusterName} - az aks create --resource-group $azureResourceGroupName \ - --name $aksClusterName \ - --vm-set-type VirtualMachineScaleSets \ - --node-count ${azureKubernetesNodeCount} \ - --generate-ssh-keys \ - --nodepool-name ${azureKubernetesNodepoolName} \ - --node-vm-size ${azureKubernetesNodeVMSize} \ - --location $azureLocation \ - --service-principal $azureServicePrincipalAppId \ - --client-secret $azureServicePrincipalClientSecret - - # Connect to AKS cluster - echo Connencting to Azure Kubernetes Service. - az aks get-credentials --resource-group $azureResourceGroupName --name $aksClusterName + echo Creating Azure Kubernetes Service ${aksClusterName} + az aks create --resource-group $azureResourceGroupName \ + --name $aksClusterName \ + --vm-set-type VirtualMachineScaleSets \ + --node-count ${azureKubernetesNodeCount} \ + --generate-ssh-keys \ + --nodepool-name ${azureKubernetesNodepoolName} \ + --node-vm-size ${azureKubernetesNodeVMSize} \ + --location $azureLocation \ + --service-principal $azureServicePrincipalAppId \ + --client-secret $azureServicePrincipalClientSecret + + # Connect to AKS cluster + echo Connencting to Azure Kubernetes Service. + az aks get-credentials --resource-group $azureResourceGroupName --name $aksClusterName } function createFileShare { - # Create a storage account - echo Check if the storage account ${storageAccountName} exists. - ret=$(az storage account check-name --name ${storageAccountName}) - nameAvailable=$(echo "$ret" | grep "nameAvailable" | grep "false") - if [ -n "$nameAvailable" ];then - echo $ret - fail "Storage account ${aksClusterName} is unavaliable." - fi + # Create a storage account + echo Check if the storage account ${storageAccountName} exists. + ret=$(az storage account check-name --name ${storageAccountName}) + nameAvailable=$(echo "$ret" | grep "nameAvailable" | grep "false") + if [ -n "$nameAvailable" ]; then + echo $ret + fail "Storage account ${aksClusterName} is unavailable." + fi - echo Creating Azure Storage Account ${storageAccountName}. - az storage account create \ - -n $storageAccountName \ - -g $azureResourceGroupName \ - -l $azureLocation \ - --sku ${azureStorageAccountSku} - - # Export the connection string as an environment variable, this is used when creating the Azure file share - export azureStorageConnectionString=$(az storage account show-connection-string \ - -n $storageAccountName -g $azureResourceGroupName -o tsv) - - # Create the file share - echo Check if file share exists - ret=$( az storage share exists --name ${azureStorageShareName} --account-name ${storageAccountName} --connection-string $azureStorageConnectionString | grep "exists" | grep false) - if [[ "$ret" == "true" ]];then - fail "File share name ${azureStorageShareName} is unavaliable." - fi + echo Creating Azure Storage Account ${storageAccountName}. + az storage account create \ + -n $storageAccountName \ + -g $azureResourceGroupName \ + -l $azureLocation \ + --sku Premium_LRS \ + --kind FileStorage \ + --https-only false \ + --default-action Deny + + echo Creating Azure NFS file share. + az storage share-rm create \ + --resource-group $azureResourceGroupName \ + --storage-account $storageAccountName \ + --name ${azureStorageShareName} \ + --enabled-protocol NFS \ + --root-squash NoRootSquash \ + --quota 100 + + configureStorageAccountNetwork + + # Echo storage account name and key + echo Storage account name: $storageAccountName + echo NFS file share name: ${azureStorageShareName} + + # Mount the file share as a volume + echo Mounting file share as a volume. + kubectl apply -f ${scOutput} + kubectl get storageclass ${azureFileCsiNfsClassName} -o yaml + kubectl apply -f ${pvcOutput} + kubectl get pvc ${persistentVolumeClaimName} -o yaml + + checkPvcState ${persistentVolumeClaimName} "Bound" +} + +function configureStorageAccountNetwork { + # get the resource group name of the AKS managed resources + local aksMCRGName=$(az aks show --name $aksClusterName --resource-group $azureResourceGroupName -o tsv --query "nodeResourceGroup") + echo ${aksMCRGName} - echo Creating Azure File Share ${azureStorageShareName}. - az storage share create -n $azureStorageShareName \ - --connection-string $azureStorageConnectionString - - # Get storage account key - azureStorageKey=$(az storage account keys list --resource-group $azureResourceGroupName \ - --account-name $storageAccountName --query "[0].value" -o tsv) - - # Echo storage account name and key - echo Storage account name: $storageAccountName - echo Storage account key: $azureStorageKey - - # Create a Kubernetes secret - echo Creating kubectl secret for Azure File Share ${azureFileShareSecretName}. - bash $dirKubernetesSecrets/create-azure-storage-credentials-secret.sh \ - -s ${azureFileShareSecretName} \ - -a $storageAccountName \ - -k $azureStorageKey - - # Mount the file share as a volume - echo Mounting file share as a volume. - kubectl apply -f ${pvOutput} - kubectl get pv ${persistentVolumeClaimName} -o yaml - kubectl apply -f ${pvcOutput} - kubectl get pvc ${persistentVolumeClaimName} -o yaml + # get network name of AKS cluster + local aksNetworkName=$(az resource list --resource-group ${aksMCRGName} --resource-type Microsoft.Network/virtualNetworks -o tsv --query '[*].name') + echo ${aksNetworkName} + + # get subnet name of AKS agent pool + local aksSubnetName=$(az network vnet subnet list --resource-group ${aksMCRGName} --vnet-name ${aksNetworkName} -o tsv --query "[*].name") + echo ${aksSubnetName} + + local aksSubnetId=$(az network vnet subnet list --resource-group ${aksMCRGName} --vnet-name ${aksNetworkName} -o tsv --query "[*].id") + echo ${aksSubnetId} + + az network vnet subnet update \ + --resource-group $aksMCRGName \ + --name ${aksSubnetName} \ + --vnet-name ${aksNetworkName} \ + --service-endpoints Microsoft.Storage + + az storage account network-rule add \ + --resource-group $azureResourceGroupName \ + --account-name $storageAccountName \ + --subnet ${aksSubnetId} + + if [ $? != 0 ]; then + fail "Fail to configure network for storage account ${storageAccountName}. Network name: ${aksNetworkName}. Subnet name: ${aksSubnetName}." + fi } function installWebLogicOperator { - echo `helm version` - helm repo add weblogic-operator https://oracle.github.io/weblogic-kubernetes-operator/charts - helm repo update - helm install weblogic-operator weblogic-operator/weblogic-operator --version "3.0.0" + echo $(helm version) + helm repo add weblogic-operator https://oracle.github.io/weblogic-kubernetes-operator/charts + helm repo update + helm install weblogic-operator weblogic-operator/weblogic-operator --version "3.3.7" } function createWebLogicDomain { - # Create WebLogic Server Domain Credentials. - echo Creating WebLogic Server Domain credentials, with user ${weblogicUserName}, domainUID ${domainUID} - bash ${dirCreateDomainCredentials}/create-weblogic-credentials.sh -u ${weblogicUserName} \ - -p ${weblogicAccountPassword} -d ${domainUID} - - # Create Container Registry Credentials. - bash $dirKubernetesSecrets/create-docker-credentials-secret.sh \ - -e ${docker-email} \ - -p ${dockerPassword} \ - -u ${dockerUserName} \ - -s ${imagePullSecretName} \ - -d container-registry.oracle.com - - # Create WebLogic Server Domain - echo Creating WebLogic Server domain ${domainUID} - bash ${dirCreateDomain}/create-domain.sh -i $domain1Output -o ${outputDir} -e -v - - kubectl apply -f ${adminLbOutput} - kubectl apply -f ${clusterLbOutput} + # Create WebLogic Server Domain Credentials. + echo Creating WebLogic Server Domain credentials, with user ${weblogicUserName}, domainUID ${domainUID} + bash ${dirCreateDomainCredentials}/create-weblogic-credentials.sh -u ${weblogicUserName} \ + -p ${weblogicAccountPassword} -d ${domainUID} + + # Create Container Registry Credentials. + bash $dirKubernetesSecrets/create-docker-credentials-secret.sh \ + -e ${docker-email} \ + -p ${dockerPassword} \ + -u ${dockerUserName} \ + -s ${imagePullSecretName} \ + -d container-registry.oracle.com + + # Create WebLogic Server Domain + echo Creating WebLogic Server domain ${domainUID} + bash ${dirCreateDomain}/create-domain.sh -i $domain1Output -o ${outputDir} -e -v + + kubectl apply -f ${adminLbOutput} + kubectl apply -f ${clusterLbOutput} } function waitForJobComplete { - attempts=0 - svcState="running" - while [ ! "$svcState" == "completed" ] && [ ! $attempts -eq 30 ]; do + local attempts=0 + local svcState="running" + while [ ! "$svcState" == "completed" ] && [ ! $attempts -eq 30 ]; do svcState="completed" attempts=$((attempts + 1)) echo Waiting for job completed...${attempts} @@ -410,25 +439,25 @@ function waitForJobComplete { # ${domainUID}-${adminServerName}, e.g. domain1-admin-server # ${domainUID}-${adminServerName}-ext, e.g. domain1-admin-server-ext # ${domainUID}-${adminServerName}-external-lb, e.g domain1-admin-server-external-lb - adminServiceCount=`kubectl get svc | grep -c "${domainUID}-${adminServerName}"` + local adminServiceCount=$(kubectl get svc | grep -c "${domainUID}-${adminServerName}") if [ ${adminServiceCount} -lt 3 ]; then svcState="running"; fi # If the job is completed, there should have the following services created, .assuming initialManagedServerReplicas=2 # ${domainUID}-${managedServerNameBase}1, e.g. domain1-managed-server1 # ${domainUID}-${managedServerNameBase}2, e.g. domain1-managed-server2 - managedServiceCount=`kubectl get svc | grep -c "${domainUID}-${managedServerNameBase}"` + local managedServiceCount=$(kubectl get svc | grep -c "${domainUID}-${managedServerNameBase}") if [ ${managedServiceCount} -lt ${initialManagedServerReplicas} ]; then svcState="running"; fi # If the job is completed, there should have no service in pending status. - pendingCount=`kubectl get svc | grep -c "pending"` + local pendingCount=$(kubectl get svc | grep -c "pending") if [ ${pendingCount} -ne 0 ]; then svcState="running"; fi # If the job is completed, there should have the following pods running # ${domainUID}-${adminServerName}, e.g. domain1-admin-server - # ${domainUID}-${managedServerNameBase}1, e.g. domain1-managed-server1 + # ${domainUID}-${managedServerNameBase}1, e.g. domain1-managed-server1 # to # ${domainUID}-${managedServerNameBase}n, e.g. domain1-managed-servern, n = initialManagedServerReplicas - runningPodCount=`kubectl get pods | grep "${domainUID}" | grep -c "Running"` + local runningPodCount=$(kubectl get pods | grep "${domainUID}" | grep -c "Running") if [[ $runningPodCount -le ${initialManagedServerReplicas} ]]; then svcState="running"; fi echo ==============================Current Status========================================== @@ -440,8 +469,7 @@ function waitForJobComplete { # If all the services are completed, print service details # Otherwise, ask the user to refer to document for troubleshooting - if [ "$svcState" == "completed" ]; - then + if [ "$svcState" == "completed" ]; then kubectl get pods kubectl get svc else @@ -451,8 +479,11 @@ function waitForJobComplete { function printSummary { if [ "${executeIt}" = true ]; then - regionJsonExcerpt=`az group list --query "[?name=='${azureResourceGroupName}']" | grep location` - tokens=($(IFS='"'; for word in $regionJsonExcerpt; do echo "$word"; done)) + regionJsonExcerpt=$(az group list --query "[?name=='${azureResourceGroupName}']" | grep location) + tokens=($( + IFS='"' + for word in $regionJsonExcerpt; do echo "$word"; done + )) region=${tokens[2]} echo "" echo "" @@ -468,30 +499,30 @@ function printSummary { echo "" if [ "${exposeAdminNodePort}" = true ]; then - adminLbIP=`kubectl get svc ${domainUID}-${adminServerName}-external-lb --output jsonpath='{.status.loadBalancer.ingress[0].ip}'` + adminLbIP=$(kubectl get svc ${domainUID}-${adminServerName}-external-lb --output jsonpath='{.status.loadBalancer.ingress[0].ip}') echo "Administration console access is available at http://${adminLbIP}:${adminPort}/console" fi echo "" - clusterLbIP=`kubectl get svc ${domainUID}-${clusterName}-external-lb --output jsonpath='{.status.loadBalancer.ingress[0].ip}'` + clusterLbIP=$(kubectl get svc ${domainUID}-${clusterName}-external-lb --output jsonpath='{.status.loadBalancer.ingress[0].ip}') echo "Cluster external ip is ${clusterLbIP}, after you deploy application to WebLogic Server cluster, you can access it at http://${clusterLbIP}:${managedServerPort}/" fi echo "" echo "The following files were generated:" - echo " ${pvOutput}" + echo " ${scOutput}" echo " ${pvcOutput}" echo " ${adminLbOutput}" echo " ${clusterLbOutput}" echo " ${domain1Output}" echo "" - + echo "Completed" } cd ${scriptDir} cd .. -export dirSampleScripts=`pwd` +export dirSampleScripts=$(pwd) export dirCreateDomain="${dirSampleScripts}/create-weblogic-domain/domain-home-on-pv" export dirCreateDomainCredentials="${dirSampleScripts}/create-weblogic-domain-credentials" export dirKubernetesSecrets="${dirSampleScripts}/create-kubernetes-secrets" @@ -530,7 +561,7 @@ if [ "${executeIt}" = true ]; then # Create WebLogic Server Domain createWebLogicDomain - + # Wait for all the jobs completed waitForJobComplete fi diff --git a/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/validate.sh b/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/validate.sh index 6477ebacfe8..8648aa12641 100755 --- a/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/validate.sh +++ b/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/validate.sh @@ -10,9 +10,7 @@ # * Azure storage account: check if it is created # * Azure file share: check if it's created # * Kubernetes secret for container registry account: check if it's created -# * Kubernetes secret for storage account: check if it's created # * Kubernetes secret for WebLogic domain: check if it's created -# * Persistent Volume: check if it's mounted and verify the status and storage class # * Persistent Volume Claim: check if it's mounted and verify the status and storage class # Initialize @@ -27,10 +25,8 @@ function usage { echo " --storage-account [Required] :Storage account name." echo " --domain-uid -d [Required] :Domain UID." - echo " --pv-name [Required] : Persistent Volume name." - echo " --pvc-name [Required] : Persistent Volume Claim name." + echo " --pvc-name [Required] : Persistent Volume Claim name." echo " --secret-docker [Required] : Name of the Kubernetes secret that stores docker account." - echo " --secret-storage [Required] : Name of the Kubernetes secret that stores Azure storage file share credentials." echo " --help -h :Help" exit $1 } @@ -87,16 +83,6 @@ while test $# -gt 0; do fi shift ;; - --pv-name*) - shift - if test $# -gt 0; then - export pvName=$1 - else - echo "Persistent Volume name is required." - exit 1 - fi - shift - ;; --pvc-name*) shift if test $# -gt 0; then @@ -117,16 +103,6 @@ while test $# -gt 0; do fi shift ;; - --secret-storage*) - shift - if test $# -gt 0; then - export secretStorage=$1 - else - echo "Secret name for Storage is required." - exit 1 - fi - shift - ;; -h|--help) usage 0 ;; *) usage 1 @@ -147,10 +123,6 @@ if [ -z ${fileShare} ]; then echo "${script}: --file-share must be specified." missingRequiredOption="true" fi -if [ -z ${pvName} ]; then - echo "${script}: --pv-name must be specified." - missingRequiredOption="true" -fi if [ -z ${pvcName} ]; then echo "${script}: --pvc-name must be specified." missingRequiredOption="true" @@ -163,10 +135,6 @@ if [ -z ${secretDocker} ]; then echo "${script}: --secret-docker must be specified." missingRequiredOption="true" fi -if [ -z ${secretStorage} ]; then - echo "${script}: --secret-storage must be specified." - missingRequiredOption="true" -fi if [ -z ${storageAccount} ]; then echo "${script}: --storage-account must be specified." missingRequiredOption="true" @@ -219,7 +187,7 @@ function validateFileShare { -n $storageAccount -g $resourceGroup -o tsv) echo Check if file share exists - ret=$( az storage share exists --name ${fileShare} --account-name ${storageAccount} --connection-string $azureStorageConnectionString | grep "exists" | grep false) + ret=$( az storage share-rm exists --name ${fileShare} --storage-account ${storageAccount} | grep "exists" | grep false) if [ -n "$ret" ];then fail "File share ${fileShare} is unavailable." fi @@ -239,44 +207,15 @@ function validateDockerSecret { fi } -function validateStorageSecret { - kubectl get secret ${secretStorage} - if [ $? -ne 0 ]; then - fail "Secret:${secretStorage} for storage is not created." - fi -} - function validateWebLogicDomainSecret { ret=$(kubectl get secrets | grep "weblogic-credentials") if [ $? -ne 0 ]; then - fail "Secret:${secretStorage} for storage is not created." + fail "Secret:weblogic-credentials is not created." fi export secretWebLogic=$(echo ${ret%% *}) } -function validatePV { - ret=$(kubectl get pv) - index=0 - for item in ${ret}; - do - index=$((index + 1)) - if [ $index -eq 12 ]; then - if [[ "$item" != "$pvName" ]];then - fail "Persistent Volume name $item does not match value $pvName." - fi - fi - - if [[ $index -eq 16 && "$item" != "Bound" ]]; then - fail "Persistent Volume status is not Bound." - fi - - if [[ $index -eq 18 && "$item" != "azurefile" ]]; then - echo "WARNING" "Storage class $item does not match azurefile, please check." - fi - done -} - function validatePVC { ret=$(kubectl get pvc) index=0 @@ -285,16 +224,12 @@ function validatePVC { index=$((index + 1)) if [ $index -eq 9 ]; then if [[ "$item" != "$pvcName" ]];then - fail "Persistent Volume name $item does not match value $pvcName." + fail "Persistent Volume Claim name $item does not match value $pvcName." fi fi if [[ $index -eq 10 && "$item" != "Bound" ]]; then - fail "Persistent Volume status is not Bound." - fi - - if [[ $index -eq 14 && "$item" != "azurefile" ]]; then - echo "WARNING" "Storage class $item does not match azurefile, please check." + fail "Persistent Volume Claim status is not Bound." fi done } @@ -321,10 +256,8 @@ function pass { echo " Azure Kubernetes Service instance: ${aksName}" echo " Azure storage account: ${storageAccount}" echo " Azure file share: ${fileShare}" - echo " Kubernetes secret for Azure storage: ${secretStorage}" echo " Kubernetes secret for Container Registry Account: ${secretDocker}" echo " Kubernetes secret for WebLogic domain: ${secretWebLogic}" - echo " Persistent Volume: ${pvName}" echo " Persistent Volume Claim: ${pvcName}" } @@ -342,12 +275,8 @@ connectAKS validateDockerSecret -validateStorageSecret - validateWebLogicDomainSecret -validatePV - validatePVC validateOperator