0
votes

We're considering to provide our own UI for WSO2, and make it work with the APIM gateway by invoking Publisher/Store REST API's.

Is there a way to strip of the UI part of WSO2 APIM and have a deployment containing only

  1. the gateway
  2. the key manager
  3. the publisher --> REST API only, no UI
  4. the store --> REST API only, no UI

Is there such bundle available out of the box? Otherwise, will it be possible to download either the GitHub source or the deployment package and tear off any UI related plugins and their dependent libraries?

2

2 Answers

0
votes

If you don't need any UI components, you may remove publisher and store jaggary web applications from repository/deployment/server/jaggaryapps location. If you checkout the source code, then you will need to checkout product repo which is in [1] and component repo which is in [2] to perform necessary changes for remove UI stuff, but it will add more complexity and take time. Without UI part, you can use REST API in 1.10.0. There is no OOTB bundle.

[1]-https://github.com/wso2/product-apim

[2]-https://github.com/wso2/carbon-apimgt

0
votes

This is our script for doing this (I will thank any bug or comment, currenty we are testing it)

#!/bin/bash
# WSO2 2.1.0
# Publish an API in several gateways, using internal REST API
# Reference
#   https://docs.wso2.com/display/AM210/apidocs/publisher/

# IMPORTANT: Change these values according your WSO2 APIM versionāˆ«
# Version 2.1.0
# declare APP_CLIENT_REGISTRATION="/client-registration/v0.11/register"
# declare -r URI_API_CTX="/api/am/publisher/v0.11"
# Version 2.1.0 update 14
declare -r APP_CLIENT_REGISTRATION="/client-registration/v0.12/register"
declare -r URI_API_CTX="/api/am/publisher/v0.12"

# Constants
declare -r URI_TOKEN="/token"
declare -r URI_API_APIS="${URI_API_CTX}/apis"
declare -r URI_API_ENVIRONMENTS="${URI_API_CTX}/environments"
declare -r URI_API_PUBLISH="${URI_API_CTX}/apis/change-lifecycle?action=Publish&apiId="
declare -r API_SCOPE_VIEW="apim:api_view"
declare -r API_SCOPE_PUBLISH="apim:api_publish"
declare -r API_SCOPE_CREATE="apim:api_create"

# Parameters
declare APIUSER=""
declare APIPASSWORD=""
declare APIMANAGER=""
declare APINAME=""
declare APIVERSION=""
declare -a APIGATEWAY
declare -i MANAGER_SERVICES_PORT=9443
declare -i MANAGER_NIOPT_PORT=8243

# Variables
# User login for aplication registration. User:Password in base64 (default admin:admin)
declare APIAUTH="YWRtaW46YWRtaW4="
# Client application token. ClientId:ClientSecret in base64
declare CLIENTTOKEN
# User access token (view)
declare ACCESSVIEWTOKEN
# User access token type (view)
declare ACCESSVIEWTOKENTYPE="Bearer"
# User access token (publish)
declare ACCESSPUBLISHTOKEN
# User access token type (publish)
declare ACCESSVIEWPUBLISHTYPE="Bearer"
# User access token (create)
declare ACCESSCREATETOKEN
# User access token type (create)
declare ACCESSVIEWCREATETYPE="Bearer"
# API internal ID
declare APIID

# echoErr
# Send message to error stream (/dev/stderr by default)

function echoErr() {
    printf "%s\n" "$*" >&2; 
}

# showHelp
# Usage info
showHelp() {
cat <<-EOF
    Usage: ${0##*/} [-u USER] [-p PASSWORD] APIMANAGER [-s ServicePort] [-n NioPTPort] APINAME APIVERSION APIGATEWAY [APIGATEWAY] ...
      Publish an API in the selected gateways

        -u USER         User name (if not defined, will ask for it)
        -p PASSWORD     User password (if not defined, will ask for it)
        -s ServicePort  Services Port in api manager host (by default 9443) 
        -n NioPTPort    Nio/PT Port in key manager host (by default 8243)
        APIMANAGER      API MANAGER / KEY MANAGER host name (e.g. apimanager.example.com)
        APINAME         API to publish (has to be in CREATED, PROTOTYPED or PUBLISH state)
        APIVERSION      API Version to publish          
        APIGATEWAYs     All of the gateway to publish the API (one or more)

    EOF
}

# getPassword
# get a password type field (without echo and double input)
function getPassword()
{
    local pwd=${3:-"NoSet"}
    local verify="_Set_No"
    local default=""

    if [ -z "$1" ] || [ -z "$2" ]
    then
        echo 'ERROR: Use getPassword "Message" VAR_NAME [default]'
        exit 1
    else
        if [ -n ${3} ]
        then
            default=$'\e[31m['${3}$']\e[0m'
        fi
        while true
        do
            read -sp "$1 $default" pwd
            echo ""
            # if empty (=Intro) use default if available
            if [ "$pwd" == "" ] && [ -n "$3" ]
            then
                pwd="$3"
                break
            fi
            # check password length
            if [ ${#pwd} -lt 6 ]
            then
                echo "Password too short. Minimum length is 6"
                continue
            else
            read -sp "Verify - $1 " verify
            echo ""
                if [ "$pwd" != "$verify" ]
                then
                    echo "Passwords do not match. Retype."
                else
                    break   
                fi
            fi
        done
        eval $2="$pwd"
    fi
}

# showGateways
# Print the list of available gateways in a friendly form
function showGateways() {
    local -i count
    local name
    local gwtype
    local endpoint

    if [ -z $1 ]
    then
        echo "Use: showGateways \$apiEnvironments"
    else

        count=$(echo $1|jq -r '.count')
        if [ "$count" -gt "0" ]
        then
                printf "%-20s %-10s %s\n" "Name" "Type" "Endpoint HTTPS" >&2
                printf "%-20s %-10s %s\n" "====================" "==========" "===============================================" >&2                                     
            for i in $(seq 0 $(( $count - 1 )) )
            do
                name=$(echo "$1"|jq -r '.list['$i'].name')
                gwtype=$(echo "$1"|jq -r '.list['$i'].type')
                endpoint=$(echo "$1"|jq -r '.list['$i'].endpoints.https')
                printf "%-20s %-10s %s\n" "$name" "$gwtype" "$endpoint" >&2         
            done
        fi
    fi
}

# validateGateway
# validate if all the gateways names (passed as parameter - global variable) are in environments
function validateGateways() {

    if [ -z $1 ]
    then
        echo "Use: validateGateways \$apiEnvironments"
        exit 1
    else
        for gateway in ${APIGATEWAY[@]}
        do
            jq -er \
                --arg gateway_name "$gateway" '
                    .list[] |
                    select(.name == $gateway_name)
                    ' <<<"$1" >/dev/null

            if [ $? -ne 0 ]
            then
                echo "ERROR: Gateway '$gateway' is not found"   >&2          
                return 1
            fi
        done
    fi
    return 0
}

# getClientToken
# Parse the answer of client registration, to get client token
# return (echo to stdout) the clientToken
function getClientToken() {
    local clientId
    local clientSecret
    local clientToken

    if [ -z $1 ]
    then
        echo "Use: getClientToken \$clientRegistration" >&2
        exit 1
    else
    # Parse answer to get ClientId and ClientSecret
        clientId=$(echo $clientRegistration|jq -r '.clientId')
        clientSecret=$(echo $clientRegistration|jq -r '.clientSecret')

        if [ "$clientId" == "" ] || [ "$clientSecret" == "" ] || [ "$clientId" == "null" ] || [ "$clientSecret" == "null" ]
        then
            return 1
        else 
            echo -n "$clientId:$clientSecret"|base64
            return 0
        fi
    fi
}

# getAccessToken
# Parse the answer of client API Login, to get client token
# return (echo to stdout) the accessToken
function getAccessToken() {
    local accessToken

    if [ -z $1 ]
    then
        echo "Use: getAccessToken \$clientAPILoginView|\$clientAPILoginPublish" >&2
        exit 1
    else
        # Parse answer to get ClientId and ClientSecret
        accessToken=$(echo $1|jq -r '.access_token')

        if [ "$accessToken" == "" ] || [ "$accessToken" == "null" ]
        then
            return 1
        else 
            echo -n "$accessToken"
            return 0
        fi
    fi
}

# getAccessTokenType
# Parse the answer of client API Login, to get client token type
# return (echo to stdout) the accessTokenType
function getAccessTokenType() {
    local tokenType

    if [ -z $1 ]
    then
        echo "Use: getAccessToken \$clientAPILoginView|\$clientAPILoginPublish" >&2
        exit 1
    else
        # Parse answer to get ClientId and ClientSecret
        tokenType=$(echo $1|jq -r '.token_type')

        if [ "$tokenType" == "" ] || [ "$tokenType" == "null" ]
        then
            return 1
        else 
            echo -n "$tokenType"
            return 0
        fi
    fi
}

# getAPIId
# Parse the answer of query API to get the API ID (checking version name)
# Thanks to https://stackoverflow.com/users/14122/charles-duffy
# return (echo to stdout) the APIID
function getAPIId() {

    if [ -z $1 ]
    then
        echo "Usage: getAPIId \$apiQuery" >&2
        exit 1
    else    
        # Parse answer to get API ID
        jq -er \
                --arg target_name "$APINAME" \
                --arg target_version "$APIVERSION" '
            .list[] |
            select(.name == $target_name) |
            select(.version == $target_version) |
            .id' <<<"$1"

    fi
}

# getAPIGatewayEnvironments
# Parse the answer of detailed query API to get the API gateway environments
# return (echo to stdout) the gateway environments
function getAPIGatewayEnvironments() {

    if [ -z "$1" ]
    then
        echo "Usage: getAPIGatewayEnvironments \$apiResource" >&2
        exit 1
    else    
        # Parse answer to get API ID
        jq -er '.gatewayEnvironments' <<<"$1"
    fi
}



# getAPIStatus
# Parse the answer of detailed query API to get the API status
# return (echo to stdout) the status
function getAPIStatus() {

    if [ -z "$1" ]
    then
        echo "Usage: getAPIStatus \$apiResource" >&2
        exit 1
    else    
        # Parse answer to get API ID
        jq -er '.status' <<<"$1"
    fi
}

# setGateways
# Update the field gatewayEnvironments in API resource from GATEWAY parameter array
# Return the new API resource update
function setGateways() {
    local gateways
    local oIFS      

    if [ -z "$1" ]
    then
        echo "Use: setGateways \$apiResource" >&2
        exit 1
    else
        oIFS="$IFS";IFS=',';gateways="${APIGATEWAY[*]}";IFS="$oIFS"
        jq -e '.gatewayEnvironments="'$gateways'"' <<<$1
    fi
}

# checkGateways
# check if the gateways has been updated correctly
function checkGateways() {
    local gateways
    local apiResourceGateways   
    local oIFS      

    if [ -z "$1" ]
    then
        echo "Use: checkGateways \$apiResourceUpdated" >&2
        exit 1
    else
        oIFS="$IFS";IFS=',';gateways="${APIGATEWAY[*]}";IFS="$oIFS"
        apiResourceGateways=$(echo $1|jq -r '.gatewayEnvironments')
        # Return value
        if [ -z "$apiResourceGateways" ] || [ "$apiResrouceGateways" == "null" ]
        then
            return 1
        fi
        # TODO: The gateways are sorted in different manner (reverse as API Manager??)
        #if [ "$gateways" != "$apiResourceGateways" ]
        #then
        #   return 1
        #fi
    fi
    return 0
}

# getParms
# Parse the parms and assign to variables
function getParms() {
    local OPTIND=1
    while getopts hu:p: opt $@
    do
        case $opt in
            h)
                showHelp
                exit 0
                ;;
            u)  
                APIUSER=$OPTARG
                ;;
            p)  
                APIPASSWORD=$OPTARG
                ;;
            s)  
                MANAGER_SERVICES_PORT=$OPTARG
                ;;
            n)  
                MANAGER_NIOPT_PORT=$OPTARG
                ;;
            *)
                showHelp >&2
                exit 1
                ;;
        esac
    done
    shift "$((OPTIND-1))"   # Discard the options and get parameter

    APIMANAGER=$1
    if [ "$APIMANAGER" == "" ]
    then
        echo "APIMANAGER host name is required"
        showHelp >&2
        exit 1
    fi
    shift 1

    APINAME=$1
    if [ "$APINAME" == "" ]
    then
        echo "API name to publish is required"
        showHelp >&2
        exit 1
    fi
    shift 1

    APIVERSION=$1
    if [ "$APIVERSION" == "" ]
    then
        echo "API version to publish is required"
        showHelp >&2
        exit 1
    fi
    shift 1

    if [ "$1" == "" ]
    then
        echo "You must indicate 1 or more gateway to publish is required"
        showHelp >&2
        exit 1
    else
        local i=1
        for arg in $@
        do
            APIGATEWAY[$i]="$1"
            let i=(i+1)
            shift 1
        done
    fi
}

###############################################################################
# Check required internal tools
if  ! type -t jq >/dev/null
then
    echo "jq not found. Install it, e.g. 'apt-get install jq'"
    exit 2
fi

# Read and parse Parms. Request required values missing
getParms $@

if [ "$APIUSER" == "" ]
then
    APIUSER=admin
    read -p $'Publisher user: \e[31m['${APIUSER}$']\e[0m ' parm
    APIUSER=${parm:-$APIUSER}   
fi

if [ "$APIPASSWORD" == "" ]
then
    APIPASSWORD=admin
    read -sp $'Publisher password: \e[31m['${APIPASSWORD}$']\e[0m ' parm
    APIPASSWORD=${parm:-$APIPASSWORD}
    echo ""
fi


# TEST ONLY: Delete (show parameter values)
# echo "USER=$APIUSER"
# echo "PASSWORD=$APIPASSWORD"
# echo "APIMANAGER=$APIMANAGER"
# echo "APINAME=$APINAME"
# for GWY in ${!APIGATEWAY[@]}
# do
#   echo "APIGATEWAY[$GWY]=${APIGATEWAY[$GWY]}"
# done


# Client registration
echo "Registering this script as a client application (rest_api_publisher)"
APIAUTH=$(echo -n $APIUSER:$APIPASSWORD|base64)
clientRegistration=$(
    curl -s -X POST "https://${APIMANAGER}:${MANAGER_SERVICES_PORT}${APP_CLIENT_REGISTRATION}" \
    -H "Authorization: Basic ${APIAUTH}" \
    -H "Content-Type: application/json" \
    -d @- <<-EOF
        {
            "callbackUrl": "www.google.lk",
            "clientName": "rest_api_publisher",
            "owner": "$APIUSER",
            "grantType": "password refresh_token",
            "saasApp": true
        }
    EOF
    )

if [ "$clientRegistration" == "" ]
then
    echo "ERROR: Empty answer from https://${APIMANAGER}:${MANAGER_SERVICES_PORT}${APP_CLIENT_REGISTRATION}. Is APIMANAGER correct?" >&2
    exit 3
fi

# Get Application Client Token
CLIENTTOKEN=$(getClientToken $clientRegistration)
if [ $? -ne 0 ]
then
    echo $clientRegistration >&2
    echo "ERROR: Cannot get ClientId/ClientSecret: Is user/password correct?" >&2
    exit 4
fi

# TEST ONLY: Delete
# echo "CLIENTTOKEN=$CLIENTTOKEN"

echo "Aplication rest_api_publisher registered"

# Client Login for get Access Token (and Token Type) - View Scope
echo "Obtaining access token for API query (scope api_view)"
clientAPILoginView=$(
    curl -s -X POST "https://${APIMANAGER}:${MANAGER_NIOPT_PORT}${URI_TOKEN}" \
    -H "Authorization: Basic ${CLIENTTOKEN}" \
    -d "grant_type=password&username=${APIUSER}&password=${APIPASSWORD}&scope=${API_SCOPE_VIEW}"
    )

ACCESSVIEWTOKEN=$(getAccessToken $clientAPILoginView) && ACCESSVIEWTOKENTYPE=$(getAccessTokenType $clientAPILoginView)
if [ $? -ne 0 ]
then
    echo $clientAPILoginView >&2
    echo "ERROR: Cannot get Access Token: Has the user '$APIUSER' in necesary role for scope ${API_SCOPE_VIEW}" >&2
    exit 5
fi

# TEST ONLY: Delete
# echo "Access View Token=$ACCESSVIEWTOKEN"
# echo "Token View Type=$ACCESSVIEWTOKENTYPE"

# Client Login for get Access Token (and Token Type) - Publish Scope
echo "Obtaining access token for API publish (scope api_publish)"
clientAPILoginPublish=$(
    curl -s -X POST "https://${APIMANAGER}:${MANAGER_NIOPT_PORT}${URI_TOKEN}" \
    -H "Authorization: Basic ${CLIENTTOKEN}" \
    -d "grant_type=password&username=${APIUSER}&password=${APIPASSWORD}&scope=${API_SCOPE_PUBLISH}"
    )

ACCESSPUBLISHTOKEN=$(getAccessToken $clientAPILoginPublish) && ACCESSPUBLISHTOKENTYPE=$(getAccessTokenType $clientAPILoginPublish)
if [ $? -ne 0 ]
then
    echo $clientAPILoginPublish >&2
    echo "ERROR: Cannot get Access Token: Has the user $APIUSER in necesary role for scope ${API_SCOPE_PUBLISH}" >&2
    exit 5
fi

# TEST ONLY: Delete
# echo "Access Publish Token=$ACCESSPUBLISHTOKEN"
# echo "Token Publish Type=$ACCESSPUBLISHTOKENTYPE"

# Client Login for get Access Token (and Token Type) - Publish Scope
echo "Obtaining access token for API create (scope api_create)"
clientAPILoginCreate=$(
    curl -s -X POST "https://${APIMANAGER}:${MANAGER_NIOPT_PORT}${URI_TOKEN}" \
    -H "Authorization: Basic ${CLIENTTOKEN}" \
    -d "grant_type=password&username=${APIUSER}&password=${APIPASSWORD}&scope=${API_SCOPE_CREATE}"
    )

ACCESSCREATETOKEN=$(getAccessToken $clientAPILoginCreate) && ACCESSCREATETOKENTYPE=$(getAccessTokenType $clientAPILoginCreate)
if [ $? -ne 0 ]
then
    echo $clientAPILoginCreate|jq . >&2
    echo "ERROR: Cannot get Access Token: Has the user $APIUSER in necesary role for scope ${API_SCOPE_CREATE}" >&2
    exit 5
fi

# TEST ONLY: Delete
# echo "Access Create Token=$ACCESSCREATETOKEN"
# echo "Token Create Type=$ACCESSCREATETOKENTYPE"

echo "All tokens obtained"

# Get API info (exists?)
echo "Checking API with name '${APINAME}' with version '${APIVERSION}' in '${APIMANAGER}'"
apiQuery=$(
    curl -s "https://${APIMANAGER}:${MANAGER_SERVICES_PORT}${URI_API_APIS}?query=name:$APINAME" \
    -H "Authorization: ${ACCESSVIEWTOKENTYPE} ${ACCESSVIEWTOKEN}" 
    )

# TEST ONLY: Delete
# echo "apiQuery=${apiQuery}"

APIID=$(getAPIId $apiQuery)
if [ $? -ne 0 ]
then
    echo $apiQuery >&2
    echo "ERROR: Cannot find an API ${APINAME} with version '${APIVERSION}' in '${APIMANAGER}'" >&2
    exit 6
fi

echo "API Found. APIID='$APIID'"

# Get availables gateways and validate gateways names
echo "Checking if requested gateways '${APIGATEWAY[@]}' are available in '${APIMANAGER}'"
apiEnvironments=$(
    curl -s "https://${APIMANAGER}:${MANAGER_SERVICES_PORT}${URI_API_ENVIRONMENTS}" \
    -H "Authorization: ${ACCESSVIEWTOKENTYPE} ${ACCESSVIEWTOKEN}" 
    )

# TEST ONLY: Delete
# echo "apiEnvironments=$apiEnvironments"

if ! validateGateways $apiEnvironments
then
    echo "Valid gateways are:"
    showGateways $apiEnvironments
    exit 7
fi

echo "API required gateways checked"

# Get API detailed info
echo "Getting API detailed info of '${APINAME}' with version '${APIVERSION}' in '${APIMANAGER}'"
apiResource=$(
    curl -s -S -f -X GET "https://${APIMANAGER}:${MANAGER_SERVICES_PORT}${URI_API_APIS}/${APIID}" \
    -H "Authorization: ${ACCESSVIEWTOKENTYPE} ${ACCESSVIEWTOKEN}" 
    )
if [ $? -ne 0 ]
then
    echo "ERROR: Cannot get API detailed information of '${APINAME}' with version '${APIVERSION}' in '${APIMANAGER}'" >&2
    exit 8
fi

# TEST ONLY: Delete
# jq . <<<$apiResource


currentGatewayEnvironments=$(getAPIGatewayEnvironments "$apiResource") && currentStatus=$(getAPIStatus "$apiResource")
if [ $? -ne 0 ]
then
    jq . <<<$apiResource >&2
    echo "ERROR: Cannot get API detailed information of '${APINAME}' with version '${APIVERSION}' in '${APIMANAGER}'" >&2
    exit 8
fi


echo "API is currently configured for gateways: '${currentGatewayEnvironments}'"
echo "API is currently in status: '${currentStatus}'"

# Update API gateways info
apiResourceUpdated=$(setGateways "$apiResource")

if [ $? -ne 0 ]
then
    echo $apiResourceUpdated | jq . >&2
    echo "ERROR: Cannot update gateways in API resource" >&2
    exit 9
fi

# TEST ONLY: Delete
jq . <<<$apiResouceUpdated >&2

# PENDING: Update also required information (e.g., Endpoints)

# Update gateways
echo "Updating API gateways of '${APINAME}' with version '${APIVERSION}' in '${APIMANAGER}' to '${APIGATEWAY[@]}'"
apiResourceUpdatedResponse=$(
    curl -s -S -f -X PUT "https://${APIMANAGER}:${MANAGER_SERVICES_PORT}${URI_API_APIS}/${APIID}" \
    -H "Content-Type: application/json" \
    -H "Authorization: ${ACCESSCREATETOKENTYPE} ${ACCESSCREATETOKEN}" \
    -d "$apiResourceUpdated"
    )
if [ $? -ne 0 ]
then
    # Retry request to show error in console
    curl -s -X PUT "https://${APIMANAGER}:${MANAGER_SERVICES_PORT}${URI_API_APIS}/${APIID}" \
    -H "Content-Type: application/json" \
    -H "Authorization: ${ACCESSCREATETOKENTYPE} ${ACCESSCREATETOKEN}" \
    -d "$apiResourceUpdated"|jq .
    echo "ERROR: Cannot update gateways in API resource. Check API for missing information (HTTP Endpoints, ...)" >&2
    exit 10
fi

# TEST ONLY: Delete
# jq . <<<$apiResourceUpdatedResponse

if ! checkGateways "$apiResourceUpdatedResponse"
then
    echo $apiResourceUpdated| jq . >&2
    echo "ERROR: Error updating gateways in API resource" >&2
    exit 9
fi

echo "API Updated"

# Publish
echo "Publishing '${APINAME}' with version '${APIVERSION}' in '${APIMANAGER}' "
apiResource=$(
    curl -s -S -f -X POST "https://${APIMANAGER}:${MANAGER_SERVICES_PORT}${URI_API_PUBLISH}${APIID}" \
    -H "Authorization: ${ACCESSPUBLISHTOKENTYPE} ${ACCESSPUBLISHTOKEN}" 
    )
if [ $? -ne 0 ]
then
    echo "ERROR: Publishing '${APINAME}' with version '${APIVERSION}' in '${APIMANAGER}'" >&2
    exit 10
fi
echo "API Published"

# Verify status and gateways
echo "Verify API detailed info of '${APINAME}' with version '${APIVERSION}' in '${APIMANAGER}'"
apiResource=$(
    curl -s -S -f -X GET "https://${APIMANAGER}:${MANAGER_SERVICES_PORT}${URI_API_APIS}/${APIID}" \
    -H "Authorization: ${ACCESSVIEWTOKENTYPE} ${ACCESSVIEWTOKEN}" 
    )
if [ $? -ne 0 ]
then
    echo "ERROR: Cannot get API detailed information of '${APINAME}' with version '${APIVERSION}' in '${APIMANAGER}'" >&2
    exit 11
fi

currentGatewayEnvironments=$(getAPIGatewayEnvironments "$apiResource") && currentStatus=$(getAPIStatus "$apiResource")
if [ $? -ne 0 ]
then
    jq . <<<$apiResource >&2
    echo "ERROR: Cannot get API detailed information of '${APINAME}' with version '${APIVERSION}' in '${APIMANAGER}'" >&2
    exit 12
fi


echo "API is now configured for gateways: '${currentGatewayEnvironments}'"
echo "API is now in status: '${currentStatus}'"