API/Python/Open-Source Solutions

 View Only

Refresh a Self Service Container from a Template Snapshot to reduce refresh time

By Diego Loureda posted 07-01-2019 01:10:29 PM

  
By default Self Service Refreshes on a container will refresh the container database or databases to the latest point in time available. We have seen that some of these refreshes may take some time. In the Oracle case, all archivelogs created after the backup have to be applied.


Our clients have been requested a way to refresh a container to the point in time where the snapshot happened in the template, but unfortunately the snapshots are not visible on the template timeline.


Here we present a workaround to be able to see snapshots in the template timeline on the Self Service screen.


On this example, the template has only one datasource.

The solution is very simple and based on the fact that bookmarks on templates are always shared, never private. So what I did is just create a post sync hook on the source (the template), that every time we do a snapsync, it will create a bookmark in the template that will be visible for all Self Service users. The hook is very simple and I used DxToolkit for it:



So every time a snapsync runs, this post sync hook will create a bookmark on the template timeline called snapsync + date:



With this simple hook, all Self Service users will have visibility to all the snapsyncs that are running on the source.

If you are not familiar with DxToolkit you must check it out. It's available here: https://github.com/delphix/dxtoolkit


If you don't want to use the DxToolkit script, as you will have to put it in all the targets, we can use a script like the one I pasted below. The good news about this approach is that all the logic to create the bookmark is stored in Delphix. This script has been tested in Red Hat Linux, may require minor changes for other Linux flavors or Unix.



On my example you can see delphix_admin is being used. If this is just not good enough in terms of security, we can just create a user with ownership on the dsource.



## This hook will create a bookmark in the template that contains this dsource

# Below Variables may change, make sure you have the proper values:
ENGINEURL=http://192.168.92.220
export URL
USR=delphix_admin
export USR
PASS=delphix
export PASS
BRANCHNAME=JS_BRANCH-1
export BRANCHNAME
SOURCEDATALAYOUT=JS_DATA_TEMPLATE-1
export SOURCEDATALAYOUT




#Below variables are fixed, no need to modify
BNAME=snapsyc-$(date +%Y-%m-%d-%H-%M-%S)
export BNAME




## Connect to the Delphix Engine
echo
echo
echo "Create session"
curl -s -X POST -k --data @- ${ENGINEURL}/resources/json/delphix/session \
    -c ~/cookies.txt -H "Content-Type: application/json" <
{
    "type": "APISession",
    "version": {
        "type": "APIVersion",
        "major": 1,
        "minor": 4,
        "micro": 0
    }
}
EOF
echo
echo
echo "Logon as:" ${USR}/${PASS}
curl -s -X POST -k --data @- ${ENGINEURL}/resources/json/delphix/login \
    -b ~/cookies.txt -H "Content-Type: application/json" <
{
    "type": "LoginRequest",
    "username": "${USR}",
    "password": "${PASS}"
}
EOF1




# Create Bookmark on Template
echo
echo
echo
echo
curl -s -X  POST -k --data @- ${ENGINEURL}/resources/json/delphix/jetstream/bookmark \
 -b ~/cookies.txt -H "Content-Type: application/json" <
{
    "type": "JSBookmarkCreateParameters",
    "bookmark": {
        "type": "JSBookmark",
        "name": "$BNAME",
        "branch": "$BRANCHNAME"
    },
    "timelinePointParameters": {
        "type": "JSTimelinePointLatestTimeInput",
        "sourceDataLayout": "$SOURCEDATALAYOUT"
    }
}
EOF1


4 comments
76 views

Comments

04-10-2020 11:29:52 AM

Hello everyone.

Latest Linux script has been updated to use python to be able to handle better the API calls results and it keeps a log of all operations in the source environment --> /tmp/create_dx_bookmark_template.log

A sample log file is the following:

[2020-04-10 12:14:12] [INFO] [connectionpool.py:203] Starting new HTTP connection (1): x.x.x.x
[2020-04-10 12:14:12] [INFO] [create_bm_self_temp.py:132] dSource reference:ORACLE_LINKED_SOURCE-13
[2020-04-10 12:14:12] [INFO] [create_bm_self_temp.py:134] dSource Container reference:ORACLE_DB_CONTAINER-47
[2020-04-10 12:14:12] [INFO] [create_bm_self_temp.py:145] dSource Config reference:ORACLE_SINGLE_CONFIG-35
[2020-04-10 12:14:12] [INFO] [create_bm_self_temp.py:155] Self Service template reference:JS_DATA_TEMPLATE-12
[2020-04-10 12:14:12] [INFO] [create_bm_self_temp.py:167] Active Branch reference:JS_BRANCH-42
[2020-04-10 12:14:12] [INFO] [create_bm_self_temp.py:169] Bookmark set to expire on : 2020-04-15T12:14:12.999Z
[2020-04-10 12:14:15] [INFO] [create_bm_self_temp.py:185] Bookmark has been created successfully! snapsync-2020-04-15T12:14:12.999Z JS_BOOKMARK-88
[2020-04-10 12:14:15] [INFO] [create_bm_self_temp.py:155] Self Service template reference:JS_DATA_TEMPLATE-13
[2020-04-10 12:14:15] [INFO] [create_bm_self_temp.py:167] Active Branch reference:JS_BRANCH-45
[2020-04-10 12:14:15] [INFO] [create_bm_self_temp.py:169] Bookmark set to expire on : 2020-04-15T12:14:12.999Z
[2020-04-10 12:14:17] [INFO] [create_bm_self_temp.py:185] Bookmark has been created successfully! snapsync-2020-04-15T12:14:12.999Z JS_BOOKMARK-89
​


It is still meant to be added as a Post-sync hook in a dSource.

Hope this helps!

Please feel free to reach out in case of questions or comments.

This is the code:
#!/bin/bash
#================================================================================
# File:         create_bookmark_template.sh
# Type:         bash-shell script
# Date:         10-Apr 2020
# Author:           v3- Carlos Cuellar - Delphix Professional Services
#                   v2- Carlos Cuellar - Delphix Professional Services
#                   v1- Diego Loureda  - Delphix Professional Services
# Ownership:    This script is owned and maintained by the user, not by Delphix
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Copyright (c) 2019 by Delphix. All rights reserved.
#
# Prerequisites:
#
#   -Python 2 installed
#   -Python Modules OS, SYS, JSON, REQUESTS, TIME and LOGGING installed --> python -c "print( help('modules'))"
#
# Description:
#
#       Script to be used as a PostSync hook on a dSource to create a new bookmark
#       on selfservice/jetstream templates where dSource is the Source.
#
#================================================================================
#
# Please set the following variables to suit your purposes.
# Set this to the Delphix admin user name
DELPHIX_ADMIN=
# Set this to the password for the Delphix admin user
DELPHIX_PASS=
#Days until bookmark expires
DXBMKEXP=
# Delphix Engine name
DelphixEngine=`echo $SSH_CLIENT|awk '{ print $1}'`


#%Y-%m-%dT%H:%M:%S.999Z

if [ -z "$DELPHIX_DATABASE_NAME" ]
then
    export DSOURCE_NAME=${DELPHIX_PDB_NAME}
elif [ -z "$DELPHIX_PDB_NAME" ]
then
    #export DSOURCE_NAME=${DELPHIX_DATABASE_NAME}
    export DSOURCE_NAME=${DELPHIX_DATABASE_UNIQUE_NAME}
else
    export DSOURCE_NAME=${DELPHIX_PDB_NAME}
fi


env > /tmp/environment.log
echo $DelphixEngine > /tmp/engine.log
echo $DSOURCE_NAME > /tmp/dsourcename.log


#Below variables are fixed, no need to modify
BNAME=snapsync-$(date +%Y-%m-%d-%H-%M-%S)
export BNAME
export DSOURCE_NAME_CONTAINER
export DSOURCE_NAME_TEMPLATE
export DSOURCE_NAME_BRANCH
export API_PATH

cat << EOF > create_bm_self_temp.py
#!/bin/python
import sys
import requests
import json
import time
import os
import logging


def _setup_logger():
    # This will log the time, level, filename, line number, and log message.
    log_message_format = '[%(asctime)s] [%(levelname)s] [%(filename)s:%(lineno)d] %(message)s'
    log_message_date_format = '%Y-%m-%d %H:%M:%S'
    # Create a custom formatter. This will help with diagnosability.
    formatter = logging.Formatter(log_message_format, datefmt= log_message_date_format)
    platform_handler = logging.FileHandler('/tmp/create_dx_bookmark_template.log')
    platform_handler.setFormatter(formatter)
    logger = logging.getLogger()
    logger.addHandler(platform_handler)
    # By default the root logger's level is logging.WARNING.
    logger.setLevel(logging.INFO)


# Setup the logger.
_setup_logger()
# logging.getLogger(__name__) is the convention way to get a logger in Python.
# It returns a new logger per module and will be a child of the root logger.
# Since we setup the root logger, nothing else needs to be done to set this
# one up.
logger = logging.getLogger(__name__)
#
# Below is an example of the repository discovery operation.
#
# NOTE: The decorators are defined on the 'plugin' object created above.
#
# Mark the function below as the operation that does repository discovery.




from datetime import datetime, timedelta


today = datetime.today()
today_date = datetime.today().strftime('%Y-%m-%d %H:%M:%S')




DMUSER=sys.argv[1]
DMPASS=sys.argv[2]
DX_ENGINE=sys.argv[3]
DX_SOURCE=sys.argv[4]
bmexp = today + timedelta(int(sys.argv[5]))
bmexpiration = bmexp.strftime('%Y-%m-%dT%H:%M:%S.999Z')
#bmexpiration = today + timedelta(int(sys.argv[6])).strftime('%Y-%m-%dT%H:%M:%S.999Z')
BASEURL='http://' + DX_ENGINE + '/resources/json/delphix'


DXBOOKMARK='snapsync-' + str(bmexpiration)


#
# Request Headers ...
#
req_headers = {
   'Content-Type': 'application/json'
}

#
# Creating log...
#
log_msg = "Starting script to create bookmarks for all templates that include dSource " + DX_SOURCE + " and they will expire on  " + str(bmexpiration)
logger.info(log_msg)

#
# Python session, also handles the cookies ...
#
session = requests.session()


#
# Create session ...
#
formdata = '{ "type": "APISession", "version": { "type": "APIVersion", "major": 1, "minor": 10, "micro": 0 } }'
r = session.post(BASEURL+'/session', data=formdata, headers=req_headers, allow_redirects=False)

#
# Login ...
#
formdata = '{ "type": "LoginRequest", "username": "' + DMUSER + '", "password": "' + DMPASS + '" }'
r = session.post(BASEURL+'/login', data=formdata, headers=req_headers, allow_redirects=False)

#
#Get all API outputs from dsources, selfservice templates and Branches
#

dxsource = session.get(BASEURL+'/source', headers=req_headers, allow_redirects=False)
dxsourceconfig = session.get(BASEURL+'/sourceconfig', headers=req_headers, allow_redirects=False)
dxdatasource = session.get(BASEURL+'/selfservice/datasource', headers=req_headers, allow_redirects=False)
dxbranch = session.get(BASEURL+'/selfservice/branch', headers=req_headers, allow_redirects=False)
dxsystem = session.get(BASEURL+'/system', headers=req_headers, allow_redirects=False)

dxsource_j = json.loads(dxsource.text)
dxsourceconfig_j = json.loads(dxsourceconfig.text)
dxdatasource_j = json.loads(dxdatasource.text)
dxbranch_j = json.loads(dxbranch.text)
dxsystem_j = json.loads(dxsystem.text)

#
# Get all references
#
for dbobj in dxsource_j['result']:
  if not dbobj['virtual']:
	if dbobj['type'] != "MSSqlStagingSource":
  		#print (dbobj['name'])
  		dxsourcename = dbobj['name']
  		if dxsourcename == DX_SOURCE:
     			dxsource_ref = dbobj['reference']
			dxcontainer_ref = dbobj ['container']




##print ("dSource reference:" + dxsource_ref)
##print ("dSource Container reference:" + dxcontainer_ref)

#
# Updating log...
#
log_msg = "dSource reference:" + dxsource_ref
logger.info(log_msg)
log_msg = "dSource Container reference:" + dxcontainer_ref
logger.info(log_msg)

for dbobj2 in dxsourceconfig_j['result']:
	if dbobj2['name'] == DX_SOURCE:
		dsourceconfig_ref = dbobj2['reference']

##print ("dSource Config reference:" + dsourceconfig_ref)
#
# Updating log...
#
log_msg = "dSource Config reference:" + dsourceconfig_ref
logger.info(log_msg)

for dbobj3 in dxdatasource_j['result']:
        if dbobj3['container'] == dxcontainer_ref:
                dx_temp_datalayout= dbobj3['dataLayout']
                ##print ("Self Service template reference:" + dx_temp_datalayout)
                #
                # Updating log...
                #
                log_msg = "Self Service template reference:" + dx_temp_datalayout
                logger.info(log_msg)


                for dbobj4 in dxbranch_j['result']:
                        if dbobj4['dataLayout'] == dx_temp_datalayout :
                                dxbranch_active = dbobj4['reference']
                                ##print ("Active Branch reference:" + dxbranch_active)
                                ##print ('Bookmark set to expire on : ' + bmexpiration)
                                #
                                # Updating log...
                                #
                                log_msg = "Active Branch reference:" + dxbranch_active
                                logger.info(log_msg)
                                log_msg = "Bookmark set to expire on : " + bmexpiration
                                logger.info(log_msg)
                                formdata = '{ "type": "JSBookmarkCreateParameters", "bookmark": { "type" : "JSBookmark", "name" : "' + DXBOOKMARK + '", "branch": "' + dxbranch_active  + '", "expiration": "' + bmexpiration + '" }, "timelinePointParameters": { "type" : "JSTimelinePointLatestTimeInput", "sourceDataLayout": "' + dx_temp_datalayout + '"} }'
                                create_bookmark = session.post(BASEURL+'/selfservice/bookmark', data=formdata, headers=req_headers, allow_redirects=False)
                                after_bm = json.loads(create_bookmark.text)
                                check_bm = after_bm['result']
                                time.sleep (2)
                                dxbookmark_chk = session.get(BASEURL+'/selfservice/bookmark', headers=req_headers, allow_redirects=False)
                                dbookmark_chk_j = json.loads(dxbookmark_chk.text)
                                #
                                for dbobjbm in dbookmark_chk_j['result']:
                                        if dbobjbm['reference'] == check_bm:
                                                ##print ('Bookmark has been created successfully! ' + dbobjbm['name'] + ' ' + dbobjbm['reference'])
                                                #
                                                # Updating log...
                                                #
                                                log_msg = "Bookmark has been created successfully! " + dbobjbm['name'] + " " + dbobjbm['reference']
                                                logger.info(log_msg)

EOF

chmod 755 create_bm_self_temp.py
python create_bm_self_temp.py $DELPHIX_ADMIN $DELPHIX_PASS $DelphixEngine $DSOURCE_NAME $DXBMKEXP
rm -f create_bm_self_temp.py
​

01-30-2019 07:31:26 PM

Hello all,

This is an updated bash script version that can be used as a post sync hook.

You only have to enter the Delphix Admin credentials and it will automatically get the DB name and will look for the SelfService templates on which this dSource is part of and will create a bookmark on the template timeline.

It will also set the expiration date 2 days from the time/date where it's taken.

Script:

#!/bin/bash
#================================================================================
# File: create_bookmark_template.sh
# Type: bash-shell script
# Date: 14-Jan 2019
# Author: v2- Carlos Cuellar - Delphix Professional Services
# v1- Diego Loureda - Delphix Professional Services
# Ownership: This script is owned and maintained by the user, not by Delphix
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Copyright (c) 2019 by Delphix. All rights reserved.
#
# Description:
#
# Script to be used as a PostSync hook on a dSource to create a new bookmark
# on selfservice/jetstream templates where dSource is the Source.
#
#================================================================================
#
# Please set the following variables to suit your purposes.
# Set this to the Delphix admin user name
DELPHIX_ADMIN=
# Set this to the password for the Delphix admin user
DELPHIX_PASS=
# Delphix Engine name
DelphixEngine=`echo $SSH_CLIENT|awk '{ print $1}'`
# Reference of dSource

if [ -z "$DELPHIX_DATABASE_NAME" ]
then
export DSOURCE_NAME=${DELPHIX_PDB_NAME}
elif [ -z "$DELPHIX_PDB_NAME" ]
then
export DSOURCE_NAME=${DELPHIX_DATABASE_NAME}
else
export DSOURCE_NAME=${DELPHIX_PDB_NAME}
fi

#Below variables are fixed, no need to modify
BNAME=snapsyc-$(date +%Y-%m-%d-%H-%M-%S)
export BNAME
export DSOURCE_NAME_CONTAINER
export DSOURCE_NAME_TEMPLATE
export DSOURCE_NAME_BRANCH
export API_PATH

# Create API session
create_api_session () {
curl -s -X POST -k --data @- https://${DelphixEngine}/resources/json/delphix/session \
-c ~/cookies.txt -H "Content-Type: application/json" <<EOF
{
"type": "APISession",
"version": {
"type": "APIVersion",
"major": 1,
"minor": 9,
"micro": 0
}
}
EOF
echo
}


# Authenticate to the DelphixEngine
authenticate_api_session () {
curl -s -X POST -k --data @- https://${DelphixEngine}/resources/json/delphix/login \
-b ~/cookies.txt -c ~/cookies.txt -H "Content-Type: application/json" <<EOF1
{
"type": "LoginRequest",
"username": "${DELPHIX_ADMIN}",
"password": "${DELPHIX_PASS}"
}
EOF1
echo
}

# Get API information for Containers, Templates and Branches
get_api_info () {
api_action=$1
case $api_action in
"source")
export ddsource=`curl --silent -X GET -k https://${DelphixEngine}/resources/json/delphix/source -b ~/cookies.txt -H "Content-Type: application/json"`
IFS=',' read -a delphixdsourcearray <<< "${ddsource}"
;;
"sourceconfig")
export ddsource=`curl --silent -X GET -k https://${DelphixEngine}/resources/json/delphix/sourceconfig -b ~/cookies.txt -H "Content-Type: application/json"`
IFS=',' read -a delphixdsourceconfigarray <<< "${ddsource}"
;;
"template")
export ddatasource=`curl --silent -X GET -k https://${DelphixEngine}/resources/json/delphix/${API_PATH}/datasource -b ~/cookies.txt -H "Content-Type: application/json"`
IFS=',' read -a delphixtemplatearray <<< "${ddatasource}"
;;
"branch")
export dbranch=`curl --silent -X GET -k https://${DelphixEngine}/resources/json/delphix/${API_PATH}/branch -b ~/cookies.txt -H "Content-Type: application/json"`
IFS=',' read -a delphixbrancharray <<< "${dbranch}"
;;
"version")
export dversion=`curl --silent -X GET -k https://${DelphixEngine}/resources/json/delphix/system -b ~/cookies.txt -H "Content-Type: application/json"`
IFS=',' read -a delphixversionarray <<< "${dversion}"
;;
esac

case $api_action in
"source")
counter=0
for i in "${delphixdsourcearray[@]}"
do
export js_col=`echo $i|awk -F":" '{ print $1}'`
export js_val=`echo $i|awk -F\":\" '{ print $2}'`
if [ "$js_col" == "\"config\"" ]||[ "$js_col" == "\"container\"" ]; then
export js_val_f4=`echo $js_val|sed 's/"//g'`
reference_dsource[$counter]="$js_val_f4"
counter=`expr $counter + 1`
fi
done
;;
"sourceconfig")
counter=0
for i in "${delphixdsourceconfigarray[@]}"
do
export js_col=`echo $i|awk -F":" '{ print $1}'`
export js_val=`echo $i|awk -F\":\" '{ print $2}'`
if [ "$js_col" == "\"name\"" ]||[ "$js_col" == "\"reference\"" ]; then
export js_val_f5=`echo $js_val|sed 's/"//g'`
reference_dsourceconfig[$counter]="$js_val_f5"
counter=`expr $counter + 1`
fi
done
;;
"template")
counter=0
for i in "${delphixtemplatearray[@]}"
do
export js_col=`echo $i|awk -F":" '{ print $1}'`
export js_val=`echo $i|awk -F\":\" '{ print $2}'`
if [ "$js_col" == "\"name\"" ] ||[ "$js_col" == "\"databaseName\"" ] ||[ "$js_col" == "\"dataLayout\"" ] ||[ "$js_col" == "\"container\"" ]; then
export js_val_f2=`echo $js_val|sed 's/"//g'`
reference_template[$counter]="$js_val_f2"
counter=`expr $counter + 1`
fi
done
;;
"branch")
counter=0
for i in "${delphixbrancharray[@]}"
do
export js_col=`echo $i|awk -F":" '{ print $1}'`
export js_val=`echo $i|awk -F\":\" '{ print $2}'`
if [ "$js_col" == "\"name\"" ]||[ "$js_col" == "\"reference\"" ]||[ "$js_col" == "\"dataLayout\"" ]; then
export js_val_f3=`echo $js_val|sed 's/"//g'`
reference_branch[$counter]="$js_val_f3"
counter=`expr $counter + 1`
fi
done
;;
"version")
counter=0
for i in "${delphixversionarray[@]}"
do
export js_col=`echo $i|awk -F":" '{ print $1}'`
export js_val=`echo $i|awk -F\":\" '{ print $2}'`
if [ "$js_col" == "\"buildTitle\"" ]; then
export js_val_f=`echo $js_val|sed 's/"//g'`
reference_version[$counter]="$js_val_f"
fi
done
if [[ ${reference_version[${counter}]} =~ .*Engine.* ]]
then
export DE_VERSION=`echo ${reference_version[${counter}]}|awk '{ print $3}'`
else
export DE_VERSION=`echo ${reference_version[${counter}]}|awk '{ print $4}'`
fi
echo "Delphix Engine version is " $DE_VERSION
DE_V1=`echo $DE_VERSION|awk -F. '{ print $1}'`
DE_V2=`echo $DE_VERSION|awk -F. '{ print $2}'`
if [ $DE_V1 -gt 4 ]; then
if [ $DE_V2 -gt 2 ]; then
export API_PATH=selfservice
else
export API_PATH=jetstream
fi
else
export API_PATH=jetstream
fi
;;
esac
}

#Get Config name to match DB name to dSource name in Delphix engine
get_config_name () {
counter=0
for j in "${reference_dsourceconfig[@]}"
do
if [ "$j" == "$DSOURCE_NAME" ]; then
pointer=`expr $counter - 1`
export DSOURCE_CONFIG_CONTAINER=${reference_dsourceconfig[${pointer}]}
echo "Source Config name is : " $DSOURCE_CONFIG_CONTAINER
fi
counter=`expr $counter + 1`
done
}

#Get the Container name to create bookmarks
get_container_name () {
counter=0
for j in "${reference_dsource[@]}"
do
if [ "$j" == "$DSOURCE_CONFIG_CONTAINER" ]; then
pointer=`expr $counter - 1`
DSOURCE_NAME_CONTAINER=${reference_dsource[${pointer}]}
echo "Container name is : " $DSOURCE_NAME_CONTAINER
fi
counter=`expr $counter + 1`
done
}


#Get Template reference and with it create bookmarks as needed
get_temp_branch_create_bookmark () {
export BMDT=$(date '+%Y-%m-%dT%H:%M:%S.999Z' --date="+2 days");
for j in "${reference_template[@]}"
do
if [ "$j" == "$DSOURCE_NAME_CONTAINER" ] ; then
DSOURCE_NAME_TEMPLATE=${k}
echo "Template name is : " $DSOURCE_NAME_TEMPLATE
len=${#reference_branch[@]}
for (( i=0; i<$len; i++ ))
do
k=${reference_branch[$i]}
if [ "$k" == "$DSOURCE_NAME_TEMPLATE" ] ; then
pointer=`expr $i - 2`
DSOURCE_NAME_BRANCH=${reference_branch[$pointer]}
echo "Branch name is : " $DSOURCE_NAME_BRANCH
create_bookmark $DSOURCE_NAME_TEMPLATE $DSOURCE_NAME_BRANCH
fi
done
fi
k=${j}
done
}


create_bookmark () {
DSOURCE_NAME_TEMPLATE_CB=$1
DSOURCE_NAME_BRANCH_CB=$2
curl -s -X POST -k --data @- https://${DelphixEngine}/resources/json/delphix/${API_PATH}/bookmark -b ~/cookies.txt -H "Content-Type: application/json" <<EOF1
{
"type": "JSBookmarkCreateParameters",
"bookmark": {
"type": "JSBookmark",
"name": "$BNAME",
"branch": "$DSOURCE_NAME_BRANCH_CB",
"expiration": "$BMDT"
},
"timelinePointParameters": {
"type": "JSTimelinePointLatestTimeInput",
"sourceDataLayout": "$DSOURCE_NAME_TEMPLATE_CB"
}
}
echo
EOF1
}

############################MAIN SCRIPT#############################

create_api_session
authenticate_api_session
get_api_info version
get_api_info source
get_api_info sourceconfig
get_config_name
get_container_name
get_api_info template
get_api_info branch
get_temp_branch_create_bookmark

exit 0

#######################END OF MAIN SCRIPT##########################​

11-05-2018 08:48:38 PM

This Powershell script can be used as a post hook to create bookmark after every snapshot.

############################### Delphix Masking and Snapshot API Calls ################################
# File: ss_bookmark_template.ps1
# Type: Powershell script
# Author: Delphix Professional Services (Created by - Jatinder Luthra)
# Date: 17-Oct-2018
#
# Copyright and license:
#
#       Licensed under the Apache License, Version 2.0 (the "License"); you may
#       not use this file except in compliance with the License.
#
#       You may obtain a copy of the License at
#     
#               http://www.apache.org/licenses/LICENSE-2.0
#
#       Unless required by applicable law or agreed to in writing, software
#       distributed under the License is distributed on an "AS IS" basis,
#       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
#       See the License for the specific language governing permissions and
#       limitations under the License.
#     
#       Copyright (c) 2018 by Delphix.  All rights reserved.
#
# Description:
#
# Powershell script to create bookmark on Self Service Template
#   
#   Parent Script: ss_bookmark_template.ps1
#   
#   Notes: This script can be called as a hook which will create a bookmark in the template that contains this dSource                           
#________________________________________________________________________________________
######################################################################################################
#########################################################
#                   DELPHIX CORP                        #
#########################################################
########################################################################################
#########################       SET THE SCRIPT PARAMETERS        #######################
########################################################################################
$SS_TEMPLATE=$args[0]
If ([string]::IsNullOrEmpty($SS_TEMPLATE)){
echo 'Please pass the Self-Service Template Name'
exit 1
}

$VIRTUALIZATION_ENGINE="http://172.16.98.25/resources/json/delphix";
$VIRT_USERNAME="delphix_admin"
$VIRT_PASSWORD="delphix"
#$SS_TEMPLATE = "PerformanceMasking"
$BOOKMARK_TIME=(Get-Date -Format yyyy-MM-dd-HH-mm-ss).ToString()
$SS_BOOKMARK = 'snapsync-'+$BOOKMARK_TIME
#####################################################################################
################         NO CHANGES REQUIRED BELOW THIS POINT        ################
#####################################################################################
#####################################################################################
####################       FUNCTION TO PARSE JSON OUTPUT         ####################
#####################################################################################
function ConvertFrom-Json20([object] $item){ 
    add-type -assembly system.web.extensions
    $ps_js=new-object system.web.script.serialization.javascriptSerializer
    #The comma operator is the array construction operator in PowerShell
    return ,$ps_js.DeserializeObject($item)
}
#########################################################
#
######## Creating Session to Virtualization Engine #######
$cookies = "cookies.txt"
$json = @"
{
    "type": "APISession",
    "version": {
        "type": "APIVersion",
        "major": 1,
        "minor": 7,
        "micro": 0
    }
}
"@
write-output $json | Out-File "session.json" -encoding utf8
$Session = $(C:\Users\dtully\Downloads\curl-7.58.0\src\curl.exe -c $cookies -sX POST --header 'Content-Type: application/json' -d "@session.json" -k "$VIRTUALIZATION_ENGINE/session")
$getsesstat = ConvertFrom-Json20 $Session
$sesstatus=$getsesstat.status
echo "##### Session Status ##### - $sesstatus"
if ("${sesstatus}" -ne "OK") {
   echo "Session to DELPHIX Virtualization Engine failed with ${sesstatus}"
   exit 1
}

################# Login to Virtualization Engine #################### 
echo " "
echo "########### Login into Virtualization Engine ############"
echo " "
$json = @"
{
    "type": "LoginRequest",
    "username": "${VIRT_USERNAME}",
    "password": "${VIRT_PASSWORD}"
}
"@
write-output $json | Out-File "login.json" -encoding utf8
$Login = $(C:\Users\dtully\Downloads\curl-7.58.0\src\curl.exe -b $cookies -sX POST --header 'Content-Type: application/json' -d "@login.json" -k "$VIRTUALIZATION_ENGINE/login")
$getloginstat = ConvertFrom-Json20 $Login
$loginstatus=$getloginstat.status
echo "##### Login Status ##### - $loginstatus"
if ("${loginstatus}" -ne "OK") {
   echo "Login to DELPHIX Virtualization Engine failed with ${loginstatus}"
   exit 1
}
#####################################################################################
################        GET Self Service TEMPLATE REFERENCE        ##################
#####################################################################################

$fetch_templates = $(C:\Users\dtully\Downloads\curl-7.58.0\src\curl.exe -b $cookies -sX GET --header 'Content-Type: application/json' -k "$VIRTUALIZATION_ENGINE/jetstream/template")
# write-output "Databases API Results: ${dbsList}"
$get_temp_list = ConvertFrom-Json20 $fetch_templates
$temp_status=$get_temp_list.status
if ("${temp_status}" -ne "OK") {
   echo "Fetch Jet Stream Templates from DELPHIX Virtualization Engine failed with ${temp_status}"
   exit 1
}
$templist = $get_temp_list.result
#### Extract Template #####
$extractemplate = $templist | where { $_.name -eq "${SS_TEMPLATE}" -and $_.type -eq "JSDataTemplate"} | Select-Object
$TEMPLATE_REFERENCE=$extractemplate.reference
echo "#### TEMPLATE REFERENCE FOR ${JS_TEMPLATE} IS #### " $TEMPLATE_REFERENCE
#####################################################################################
################        GET Self Service BRANCH REFERENCE        ##################
#####################################################################################
$fetch_branches = $(C:\Users\dtully\Downloads\curl-7.58.0\src\curl.exe -b $cookies -sX GET --header 'Content-Type: application/json' -k "$VIRTUALIZATION_ENGINE/jetstream/branch")
$get_br_list = ConvertFrom-Json20 $fetch_branches
$branch_status=$get_br_list.status
if ("${branch_status}" -ne "OK") {
   echo "Fetch Jet Stream Branches from DELPHIX Virtualization Engine failed with ${branch_status}"
   exit 1
}
$branchlist= $get_br_list.result
#### Extract Branch #####
$extractbranch = $branchlist | where { $_.name -eq 'master' -and $_.dataLayout -eq ${TEMPLATE_REFERENCE}} | Select-Object
$BRANCH_REFERENCE=$extractbranch.reference
echo "#### BRANCH REFERENCE FOR ${SS_BRANCH} IS #### " $BRANCH_REFERENCE
#####################################################################################
################         Bookmark Template and Track Progress        ################
#####################################################################################
echo " "
echo "########### Creating Bookmark on Self Service Template - ${SS_TEMPLATE} ############"
echo " "
$bookmark_param = @"
{
    "type": "JSBookmarkCreateParameters",
    "bookmark": {
        "type": "JSBookmark",
        "name": "$SS_BOOKMARK",
        "branch": "$BRANCH_REFERENCE"
    },
    "timelinePointParameters": {
        "type": "JSTimelinePointLatestTimeInput",
        "sourceDataLayout": "$TEMPLATE_REFERENCE"
    }
}
"@
write-output $bookmark_param | Out-File "bookmark.json" -encoding utf8
$bookmark_template = $(C:\Users\dtully\Downloads\curl-7.58.0\src\curl.exe -b $cookies -sX POST --header 'Content-Type: application/json' -d "@bookmark.json" -k "$VIRTUALIZATION_ENGINE/jetstream/bookmark")
$getbmstat = ConvertFrom-Json20 $bookmark_template
$bm_status=$getbmstat.status
echo "##### GET Bookmark Status ##### - $bm_status"
if ("${bm_status}" -ne "OK") {
   echo "Bookmark of Template "${SS_TEMPLATE}" failed with ${bm_status}"
   exit 1
}
$bm_jobID = $getbmstat.job
echo " "
echo "###### Bookmark Creation JOBID ##### - $bm_jobID "
echo " "
################ Tracking Bookmark Creation Progress ################

echo "############### Tracking Bookmark Status of Template - $SS_TEMPLATE ####################"
$sleepTimer=1
DO {
   Start-Sleep $sleepTimer
$bm_job = $(C:\Users\dtully\Downloads\curl-7.58.0\src\curl.exe -b $cookies -sX GET --header 'Content-Type: application/json' -k "$VIRTUALIZATION_ENGINE/job/$bm_jobID")
$getjobstat = ConvertFrom-Json20 $bm_job
$jobState=$getjobstat.result.jobState
echo "####### Current Status of Bookmark ${SS_BOOKMARK} Creation ####### - $jobState"
} WHILE ($jobState -eq'RUNNING')
echo " "
echo "####### Self Service Bookmark, ${SS_BOOKMARK} created on Template, ${SS_TEMPLATE} ####### - $jobState"
exit 0

################ END OF SCRIPT ###############

~Thanks
Jatinder Luthra