Creating and deleting apps in bulk with qlik-cli

Overview

This tutorial covers bulk creation and deletion of apps featured in the "Do More with Qlik" webinar series.

You are going to learn how to perform bulk operations using qlik-cli with Powershell and Bash.

Prerequisites

  • An active Qlik Sense SaaS tenant
  • qlik-cli@1.00 or greater
  • Text editor for manipulating Powershell or Bash scripts

Creating apps and retrieving appIds

Consider a scenario where you need to automate creating multiple Qlik apps at one time. You work for a commercial power company and need to slice apps by region so the sales teams only see the relevant information related to their territory. As the BI administrator, you don't want to have to do this slicing manually so you open powershell and write the following code.

Powershell createApps

Begin with creating a function in the powershell script that checks if an app exists in the tenant.

function appExists {
    param([String] $appName)
    $result = qlik item ls --resourceType app --name $appName | ConvertFrom-Json
    return $result[0].resourceId
}

The appExists function takes an appName parameter and sends the value to qlik-cli using the item list command. The command pipes the response to the ConvertFrom-Json function to transform the content into a system.object type. The return value is the resource Id for the app, also known as the appId.

Next, create an empty array for collecting the appIds returned in this script.

$appIds = @()

From the example in the video, a for loop counts from 0 to 9 to generate fake app names. In a real-life example, you may have an array of values or app names available to pass into the loop.

For ($i=0; $i -lt 10; $i++) {
    $appName = "cli-app-$i"
    $app = appExists -appName $appName

    #If the appExists function returns false then use the `qlik app create` command
    if(!$app)
    {
     $app = qlik app create --attributes-name $appName -q | Out-String
    }

    #Add the appId (resourceId) to the array
    $appIds += $app
}
return $appIds

The for..loop takes the value passed in and appends it to the app name. Then, the appExists function is called to evaluate if the app exists in the tenant. If the app doesn't exist, the qlik app create command using the --attributes-name flag is used to pass the name for the new app along with -q which quiets the response from the cli to provide only the appId. The appId gets piped out to a string stored in the $app variable and added to the array.

As the script completes, the contents of the array are returned to the calling command.

Bash createApps

Bash scripting is a bit different than powershell, but equally as powerful. Here is how the script compares.

Like the previous script, begin with creating a function in the bash script that evaluates if an app exists in the tenant.

appExists() {
    local appName=${1}
    local result=$(qlik item ls --resourceType app --name ${appName} | jq -r .[0].resourceId)
    echo ${result}
}

Some subtle differences can be seen here from the powershell version. The app name parameter is passed in as a generic argument ${1} and is sent through to qlik through qlik item ls using the --name flag. The response is piped to jq, a json parser for bash, assigning the raw resourceId response to the result variable. If the result is empty then the function returns null otherwise it sends back the appId.

Next, create an empty array for collecting the appIds returned in this script.

appIds=()

Bash does for loops a bit different than powershell. In this example, supplying a range to iterate through helps with create the app name. The appExists function is called to evaluate if the app exists in the tenant. If the app doesn't exist, the qlik app create command using the --attributes-name flag is used to pass the name for the new app along with -q which quiets the response from the cli to provide only the appId. The appId gets piped out to a string stored in the $app variable and added to the array.

for i in {0..9}
do
    appName="cli-app-${i}"
    app=$(appExists ${appName})
    #echo ${app}
    #If the appExists function returns false then use the `qlik app create`
    #command
    if [ -n "${app}" ]
    then
        app=$(qlik app create --attributes-name ${appName} -q)
        echo "${app} created"
    else
        echo "${appName} exists with appID ${app}. It will not be created again."
    fi
    #Add the appId (resourceId) to the array
    appIds+=(${app})
done

As the script completes, the contents of the array are returned to the calling command.

echo ${appIds[*]}

Running these scripts results in ten apps created in your tenant. You can copy the scripts in their entirety in the Complete scripts section below.

Deleting apps in case you want to start over again

Sometimes, automating app creation can lead to some unfavorable app creep in your tenant. Here are powershell and bash scripts for deleting apps from a tenant.

Powershell deleteApps

qlik-cli's item ls command has a --name switch you can use to return items matching a string pattern. In this example, the --resourceType switch limits results to apps and the --limit switch controls how many results are returned in a single call. The limit switch is covered in an upcoming pagination tutorial.

$apps = qlik item ls --resourceType app --limit 100 --name 'cli-app' 

Take the list of apps returned from the item command and use ConvertFrom-Json to change the variable into a system.object collection.

$js = $apps | ConvertFrom-Json

Loop through the objects and use the item command again to get the item id from the tenant database. Deleting an app is a two step procedure. The first call removes the app completely from the tenant, and the second call removes the reference from the items collection.

foreach($app in $js) {
    $itemId = qlik item ls --resourceType app --resourceId $app.resourceId -q
    qlik app rm $app.resourceId
    qlik item rm $itemId
}

Bash deleteApps

qlik-cli's item ls command has a --name switch you can use to return items matching a string pattern. In this example, the --resourceType switch limits results to apps and the --limit switch controls how many results are returned in a single call. The limit switch is covered in an upcoming pagination tutorial.

With Bash, jq is used to parse the JSON response from the items API. The jq command jq -r '.[] | .resourceId' loops through the JSON array.

name="cli-app"
app=$(qlik item ls --resourceId app --limit 100 --name "${name}" | jq -r '.[] | .resourceId')

Loop through the objects and use the item command again to get the item id from the tenant database. Deleting an app is a two step procedure. The first call removes the app completely from the tenant, and the second call removes the reference from the items collection.

for resourceId in ${app[*]}
do
    itemId=$(qlik item ls --resourceType app --resourceId ${resourceId} -q)
    qlik app rm ${resourceId}
    qlik item rm ${itemId}
    echo "deleted ${itemId} with resourceId ${resourceId}"
done

Summary

All done Check out part 2 to learn more about working with spaces.

Complete scripts

Powershell scripts

#Creates Apps if they don't exist in a Qlik Sense SaaS tenant

#appExists uses the `qlik item ls` command to return the appId of an app,
#which is known as the resourceId in the items API response
function appExists {
    param([String] $appName)
    $result = qlik item ls --resourceType app --name $appName | ConvertFrom-Json
    return $result[0].resourceId
}

#Create an array to store appIds
$appIds = @()

#This example shows a for...loop to create apps, but it could easily loop
#through field values to create an app based on an array of regions
For ($i=0; $i -lt 10; $i++) {
    $appName = "cli-app-$i"
    $app = appExists -appName $appName

    #If the appExists function returns false then use the `qlik app create` command
    if(!$app)
    {
     $app = qlik app create --attributes-name $appName -q | Out-String
    }

    #Add the appId (resourceId) to the array
    $appIds += $app
}

#return the array
return $appIds

#!powershell

#Using the name flag with a search string will return items with an app type
#containing the supplied string
$apps = qlik item ls --resourceType app --limit 100 --name 'cli-app' 

#The Json response gets converted into an array of system.object objects
$js = $apps | ConvertFrom-Json

#Loop through the array, obtain the appId (resourceId) and call the rm command
#on the app command and the item command
foreach($app in $js) {
    $itemId = qlik item ls --resourceType app --resourceId $app.resourceId -q
    qlik app rm $app.resourceId
    qlik item rm $itemId
}

Bash scripts

#Creates Apps if they don't exist in a Qlik Sense SaaS tenant

#appExists uses the `qlik item ls` command to return the appId of an app, which
#is known as the resourceId in the items API response

appExists() {
    local appName=${1}
    local result=$(qlik item ls --resourceType app --name ${appName} | jq -r .[0].resourceId)
    echo ${result}
}

#Create an array to store appIds
appIds=()

#This example shows a for...loop to create apps, but it could easily loop
#through field values to create an app based on an array of regions
for i in {0..9}
do
    appName="cli-app-${i}"
    app=$(appExists ${appName})
    #echo ${app}
    #If the appExists function returns false then use the `qlik app create`
    #command
    if [ -n "${app}" ]
    then
        app=$(qlik app create --attributes-name ${appName} -q)
        echo "${app} created"
    else
        echo "${appName} exists with appID ${app}. It will not be created again."
    fi
    #Add the appId (resourceId) to the array
    appIds+=(${app})
done

#return the array
echo ${appIds[*]}

#!/bin/bash

#Using the name flag with a search string will return items with an app type
#containing the supplied string
#jq is used with bash to parse the JSON response and get the appIds for the apps

name="cli-app"
app=$(qlik item ls --resourceId app --limit 100 --name "${name}" | jq -r '.[] | .resourceId')

#loop through the app array that is created and get the itemId for the app
#When deleting apps, two calls need to be made to delete the app. The first call
#uses the app command to remove the app. The second removes the app reference
#from the items collection.
for resourceId in ${app[*]}
do
    itemId=$(qlik item ls --resourceType app --resourceId ${resourceId} -q)
    qlik app rm ${resourceId}
    qlik item rm ${itemId}
    echo "deleted ${itemId} with resourceId ${resourceId}"
done