#!/bin/sh # # ============LICENSE_START=============================================== # org.onap.dmaap # ======================================================================== # Copyright (c) J. F. Lucas. All rights reserved. # # ======================================================================== # 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. # ============LICENSE_END================================================= PROVURL=${PROVURL:-"http://dmaap-dr-prov:8080"} DRCONFIGDIR=${DRCONFIGDIR:-"/opt/app/config"} ONBEHALFHDR="X-DMAAP-DR-ON-BEHALF-OF: drprovcl" FEEDTYPE="Content-Type: application/vnd.dmaap-dr.feed" SUBTYPE="Content-Type: application/vnd.dmaap-dr.subscription" APPCONFIGINPUT=${APPCONFIGINPUT:-"/config-input"} APPCONFIG=${APPCONFIG:-"/config"} function logit() { # Direct log entries to stderr because to # allow logging inside functions that use # stdout to return values echo $(date -u -Ins)\|"$@" >&2 } function getFeedByNameVer() { # Get feed info using name and version # $1 -- Feed name (arbitrary string without embedded '"') # $2 -- Feed version (arbitrary string without embedded '"') # Returns feed data and exits with 0 if # feed is found. # Returns empty string and exits with 1 in # any other case. # Construct urlencoded query local NAME="$(printf %s "$1" | tr -d '"' | jq -R -r @uri)" local VER="$(printf %s "$2" | tr -d '"' | jq -R -r @uri)" local QUERYURL="${PROVURL}"/?"name=${NAME}"\&version="${VER}" local FEEDDATA # Make the query # Not checking exact cause for error, # just looking for success or not. local RV=1 if FEEDDATA=$(curl --fail -s -H "${ONBEHALFHDR}" "${QUERYURL}") then echo ${FEEDDATA} RV=0 fi return ${RV} } function subscriptionExists() { # See if there a subscription to the feed # that has the specified username, password, # and delivery URL. # $1 -- subscribe URL for the feed # $2 -- username for the subscription # $3 -- password for the subscription # $4 -- delivery URL for the subscription # Sets a return value of 0 if a matching # subscription is found and echoes the # corresponding subscription URL. # Others sets a return value of 1 and # echoes an empty string. local RV=1 local SUBRESP local SUBDATA local SUBLIST # Query the feed's subscribe URL to get a # list of the URLs for existing subscriptions if SUBRESP=$(curl -s --fail -H "${ONBEHALFHDR}" "$1") then # Loop through the list of existing subscriptions while read -r SUBURL # read from $SUBRESP (see redirect on "done") do # Retrieve subscription data from the subscription's URL if SUBDATA=$(curl -s --fail -H "${ONBEHALFHDR}" "${SUBURL}") then local SUBUSER=$(echo ${SUBDATA} | jq -r .delivery.user) local SUBPASS=$(echo ${SUBDATA} | jq -r .delivery.password) local SUBDELURL=$(echo ${SUBDATA} | jq -r .delivery.url) if [ "$2" = "${SUBUSER}" -a "$3" = "${SUBPASS}" -a "$4" = "${SUBDELURL}" ] then RV=0 #TRUE break fi else # This will happen, for instance, if the name in # in the "X-DMAAP-DR-ON-BEHALF-OF" header doesn't # match the owner of the feed. (Not likely in # the ONAP use case, but possible.) Could also be # the result of connectivity issues, bad URL,... logit "WARNING: Could not retrieve ${SUBURL}" fi done < <(echo ${SUBRESP} | jq -r .[]) else logit "ERROR: failed to fetch subscription list from $1" fi echo ${SUBURL} return ${RV} } function createFeedFromFile() { # Create a feed using information from a JSON file # Note that creating a feed also creates the publisher # $1 -- Path to JSON file # Returns feed data from the DR provisioning node # and exits with 0 if the feed is created. # Returns empty string and exits with 1 in # any other case. local FEEDDATA local RV=1 if test -f "$1" then # Substitute any environment variables in the subscription file local FEEDREQUEST=$(envsubst < "$1") if FEEDDATA=$(curl --fail -s --data-ascii "${FEEDREQUEST}" -H "${ONBEHALFHDR}" -H "$FEEDTYPE" ${PROVURL}/) then echo ${FEEDDATA} RV=0 fi fi return ${RV} } function createSubscriptionFromFile() { # Create a subscription to a feed from a JSON file # if a subscription with the same username, password # and delivery URL doesn't already exist. # We don't want multiple subscriptions if for some # reason a subscriber's pod is redeployed. # $1 -- JSON file defining the subscription # local SUBURL local SUBDATA local EXISTINGSUB local RV=1 if test -f "$1" then # Extract feed name and version from the JSON file local FEEDNAME=$(jq '.feed.name' "$1") local FEEDVER=$(jq '.feed.version' "$1") # Extract subscription parameters from the JSON file # (needed for checking if there's an existing subscription) local SUBUSER=$(jq -r '.delivery.user' "$1") local SUBPASS=$(jq -r '.delivery.password' "$1") local SUBDELURL=$(jq -r '.delivery.url' "$1") # Look up the feed and get the subscribe URL if SUBURL=$(getFeedByNameVer "${FEEDNAME}" "${FEEDVER}" | jq -r .links.subscribe) then # Check whether a matching subscription already exists if EXISTINGSUB=$(subscriptionExists ${SUBURL} ${SUBUSER} ${SUBPASS} ${SUBDELURL}) then logit "Using existing subscription: ${EXISTINGSUB}. No new subscription created." RV=0 else # Substitute any environment variables in the subscription file local SUBREQUEST=$(envsubst < "$1") # Create the subscription if SUBDATA=$(curl --fail -s --data-ascii "${SUBREQUEST}" -H "${ONBEHALFHDR}" -H "${SUBTYPE}" ${SUBURL}) then logit "Created new subscription: $(echo ${SUBDATA} | jq -r '.links.self')" RV=0 fi fi fi fi return ${RV} } function createOrGetFeed() { # Retrieve feed data from the DR provisioning node for # the feed described in a JSON file. If the feed # does not exist, create the file. # $1 -- Path to JSON file # Returns feed data from the DR provisioning node # if the feed exists or if it has been successfully # created, and exits with 0. # Returns empty string and exits with 1 in # any other case. local FEEDDATA local RV=1 if test -f "$1" then # Extract feed name and version from file local NAME=$(cat "$1" | jq .name) local VER=$(cat "$1" | jq .version) # Check whether feed already exists # (DR does not allow two feeds with same name and version) if FEEDDATA=$(getFeedByNameVer "${NAME}" "${VER}") then logit "Using existing feed: $(echo ${FEEDDATA} | jq -r '.links.self'). No new feed created." RV=0 else # Create feed if FEEDDATA=$(createFeedFromFile "$1") then logit "Created new feed: $(echo ${FEEDDATA} | jq -r '.links.self')" >&2 RV=0 fi fi fi echo ${FEEDDATA} return $RV } function provisionFeeds() { # Create a feed for each JSON file in the # directory specified in $1, unless the # a feed with the same name and version # already exists, in which case use the # information for the existing feed. # $1 -- Path to directory containing JSON # files defining DR feeds local FEEDDATA if test -d "$1" then for FEEDFILE in $(ls "$1"/*.json) do logit "Creating feed from ${FEEDFILE}" if FEEDDATA=$(createOrGetFeed ${FEEDFILE}) then # Set environment variables with result data # Note that FEEDNUM is taken from the number that's embedded # in the file defining the feed. FEEDNUM=$(echo "${FEEDFILE}" | sed 's/^.*\/.*-\([0-9]\+\).json/\1/') export DR_FEED_PUBURL_${FEEDNUM}="$(echo ${FEEDDATA} | jq '.links.publish')" export DR_FEED_LOGURL_${FEEDNUM}="$(echo ${FEEDDATA} | jq '.links.log')" fi done fi } function provisionSubscriptions() { # Create a subscription for each JSON file in the # directory specified in $1 # $1 -- Path to directory containing JSON # files definining DR subscriptions # Note that when provisioning a subscription to a feed, # the DR API doesn't return any additional information # that the subscriber needs. Hence no information is # extracted from the DR API response, and no environment # variables are exported (unlike the provisionFeeds function.) if test -d "$1" then for SUBFILE in $(ls "$1"/*.json) do logit "Creating subscription from ${SUBFILE}" createSubscriptionFromFile ${SUBFILE} done fi } function updateConfigurations() { # Run envsubst against each file in $1 (the application # configuration input directory) to create a corresponding # file in $2 (the application configuration directory) with # environment variables replaced by the values set in the # provisioning steps. The file(s) in $2 will be used by # the application to get (among other things) the information # needed to work with DR feeds. # $1 -- path to application configuration input directory # $2 -- path to application configuration directory cd "$1" for CONFFILE in $(ls -1) do logit "Substituting environment vars in ${CONFFILE}" envsubst <${CONFFILE} > "$2"/${CONFFILE} done } set -ue provisionFeeds ${DRCONFIGDIR}/feeds provisionSubscriptions ${DRCONFIGDIR}/dr_subs updateConfigurations ${APPCONFIGINPUT} ${APPCONFIG}