Skip to content

Commit

Permalink
Generate application access URLs from available information (inc. ing…
Browse files Browse the repository at this point in the history
…ress) (#82)
  • Loading branch information
gsmith-sas committed Mar 15, 2021
1 parent 882004c commit f017b38
Show file tree
Hide file tree
Showing 8 changed files with 276 additions and 27 deletions.
194 changes: 194 additions & 0 deletions bin/service-url-include.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
#!/bin/bash

# Copyright © 2021, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

source bin/common.sh

declare -A json_paths
# k8s object: ingress
json_paths["host"]='{.spec.rules[0].host}'
json_paths["path"]='{.spec.rules[0].http.paths[0].path}'
json_paths["tls"]='{.spec.tls[0]}'
# k8s object: service
json_paths["service_type"]='{.spec.type}'
json_paths["service_nodeport"]='{.spec.ports[0].nodePort}'
json_paths["service_http_port"]='{.spec.ports[?(@.name=="http")].port}'
json_paths["service_https_port"]='{.spec.ports[?(@.name=="https")].port}'

function get_k8s_info {
local namespace object info_item info rc

namespace=$1
object=$2
info_item=$3

info=$(kubectl -n $namespace get $object -o=jsonpath=${json_paths[$info_item]})
rc=$?

if [ "$rc" == "0" ]; then
echo "$info"
else
echo ""
return 1
fi
}

function get_ingress_ports {

if [ -z "$ingress_http_port" ]; then

ingress_namespace="${NGINX_NS:-ingress-nginx}"

ingress_service="service/ingress-nginx-controller"

ingress_http_port=$(get_k8s_info "$ingress_namespace" "$ingress_service" "service_http_port")
if [ -z "$ingress_http_port" ]; then
ingress_http_port=80
fi

ingress_https_port=$(get_k8s_info "$ingress_namespace" "$ingress_service" "service_https_port")
if [ -z "$ingress_https_port" ]; then
ingress_https_port=443
fi
fi
}

function get_ingress_url {

local namespace name host path tls_info rc port porttxt protocol

namespace=$1
name=$2

if [ ! "$(kubectl -n $namespace get ingress/$name 2>/dev/null)" ]; then
# ingress object does not exist
return 1
fi

host=$(get_k8s_info "$namespace" "ingress/$name" "host")
if [ -z "$host" ]; then
return 1
fi

path=$(get_k8s_info "$namespace" "ingress/$name" "path")
if [ -z "$path" ]; then
return 1
fi

tls_info=$(get_k8s_info "$namespace" "ingress/$name" "tls")
rc=$?
if [ "$rc" == "0" ]; then
port=$ingress_https_port
protocol=https
else
port=$ingress_http_port
protocol=http
fi

if [ ! -z "$port" ]; then
porttxt=":$port"
fi

url="$protocol://${host}${porttxt}${path}"
echo "$url"
}

function get_nodeport_url {
local host path tls_enabled port porttxt protocol

namespace=$1
service=$2
path=$3
tls_enabled=$4

if [ ! "$(kubectl -n $namespace get service/$service 2>/dev/null)" ]; then
# ingress object does not exist
return 1
fi


# DEPRECATION: use of the NODE_NAME env var to override the node name used in the Kibana URL has been
# deprecated with release 1.0.5 (09MAR21) and will support removed completely in an upcoming release
host=${NODE_NAME:-$(kubectl get node --selector='node-role.kubernetes.io/master' | awk 'NR==2 { print $1 }')}
if [ -z "$host" ]; then
host=$(kubectl get nodes | awk 'NR==2 { print $1 }') # use first node
fi

port=$(get_k8s_info "$namespace" "service/$service" "service_nodeport")

if [ "$tls_enabled" == "true" ]; then
protocol=https
else
protocol=http
fi

if [ ! -z "$port" ]; then
porttxt=":$port"
fi

url="$protocol://${host}${porttxt}${path}"
echo "$url"
}


function get_service_url {

local namespace service path use_tls ingress service_type url

namespace=$1
service=$2 # name of service
path=$3 # only used for NodePort? Appended to path returned by ingress objects
use_tls=$4 # use http or https (ingress properties over-ride)
ingress=${5:-${service}} # (optional) name of ingress object (default: $service)

# determine nodePort or clusterPort (ingress)
service_type=$(get_k8s_info "$namespace" "service/$service" "service_type")

if [ "$service_type" == "ClusterIP" ]; then

get_ingress_ports

url=$(get_ingress_url $namespace $ingress)

if [ -z "$url" ]; then
return 1
else
echo "$url"
fi

elif [ "$service_type" == "NodePort" ]; then

url=$(get_nodeport_url $namespace $service $path $use_tls)

if [ -z "$url" ]; then
return 1
else
echo "$url"
fi
else
# uh-oh, how what?
return 1
fi
}

# USAGE NOTES
#
# #Exit on error
#
# These functions return with a non-zero return code when unable to generate the requested URL;
# therefore, you may need to set +e before calling these functions if you want to handle that exception
# rather than having the calling script fail.
#
# #Setting ingress_http_port and ingress_https_port variables
#
# * The get_service_url function assumes variables ingress_http_port and ingress_https_port have been set
# * call get_ingress_ports function to set these variables or set them by hand
#
# # Sample usage:
# grafana_url=$(get_service_url monitoring v4m-grafana "/" "false")
#
# Returns generated URL or "" (null) string (if unable to generate URL)
# Exit code: 0 = success 1 = failure to generate URL
#

18 changes: 4 additions & 14 deletions logging/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,23 +239,13 @@ The script removes configmaps and secrets that were created by the deployment sc

### Access Kibana

If the deployment process completes without errors, a message such as this
appears in the console window:
If the deployment process completes without errors, a message
appears in the console window containing the URL address for Kibana and the URL for Elasticsearch (if you enabled access to Elasticsearch). The URL for Kibana is different depending on whether you use nodeports or ingress to access Kibana.

```text
=====================================================================
== Access Kibana using this URL: http://myK8snode:31033/app/kibana ==
=====================================================================
```

The message provides the URL address for the Kibana application. To validate
that the deployment was successful and confirm that all of the logging components
To validate that the deployment was successful and confirm that all of the logging components
are working, access Kibana and review the log messages that are collected.

__Note:__ The displayed URL for Kibana might not be correct if you defined
ingress objects or if your networking rules alter how hosts are accessed. If
this is the case, contact your Kubernetes administrator to determine the proper
host, port and/or path to access Kibana.
__Note:__ The displayed URL for Kibana might not be correct if your networking rules alter how hosts are accessed. If this is the case, contact your Kubernetes administrator to determine the proper host, port and/or path to access Kibana.

### Use Kibana to Validate Logging

Expand Down
35 changes: 30 additions & 5 deletions logging/bin/deploy_kibana_content.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
cd "$(dirname $BASH_SOURCE)/../.."
source logging/bin/common.sh
source logging/bin/secrets-include.sh
source bin/service-url-include.sh

this_script=`basename "$0"`

Expand Down Expand Up @@ -167,15 +168,39 @@ rm -f $tmpfile
sleep 7s


set +e
# call function to get HTTP/HTTPS ports from ingress controller
get_ingress_ports

# get URLs for Kibana and Elasticsearch REST api endpoint
kb_url=$(get_service_url $LOG_NS v4m-es-kibana-svc "/" "$LOG_KB_TLS_ENABLE" "v4m-es-kibana")
es_url=$(get_service_url $LOG_NS v4m-es-client-service "/" "true")
set -e

# Print URL to access Kibana
add_notice ""
add_notice "================================================================================"
add_notice "== Access Kibana using this URL: =="
add_notice "== =="
add_notice "== $KB_CURL_PROTOCOL://$NODE_NAME:$KIBANA_PORT/app/kibana =="
add_notice "== Accessing the monitoring applications =="
add_notice "== =="
add_notice "== Note: If you have configured INGRESS, this URL may be incorrect; review =="
add_notice "== the INGRESS configuration to determine correct URL to access Kibana. =="
add_notice "== ***KIBANA*** =="
if [ ! -z "$kb_url" ]; then
add_notice "== You can access Kibana via the following URL: =="
add_notice "== $kb_url =="
add_notice "== =="
else
add_notice "== It was not possible to determine the URL needed to access Kibana. Note =="
add_notice "== that this is not necessarily a sign of a problem; it may only reflect an =="
add_notice "== ingress or network access configuration that this script does not handle. =="
add_notice "== =="
fi
if [ ! -z "$es_url" ]; then
add_notice "== ***Elasticsearch REST Endpoint*** =="
add_notice "== You can access Elasticsearch REST endpoint via the following URL: =="
add_notice "== $es_url =="
add_notice "== =="
fi
add_notice "== Note: These URLs may be incorrect if your ingress and/or other network =="
add_notice "== configuration includes options this script does not handle. =="
add_notice "================================================================================"
add_notice ""

Expand Down
4 changes: 3 additions & 1 deletion logging/user.env
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,10 @@



# Kibana hostname override for Ingress and/or DNS Alias
# Kibana hostname override for Ingress and/or DNS Alias (***DEPRECATED 09MAR21**)
# ------------------------------
# ***** USE OF THIS ENV VAR HAS BEEN DEPRECATED AND SUPPORT *****
# ***** FOR IT WILL BE REMOVED ENTIRELY IN AN UPCOMING RELEASE *****
# NODE_NAME specifies the host used by logging to communicate with Kibana
# The default is a node labeled with node-role.kubernetes.io/master
# followed by the first node returned by 'kubectl get nodes'
Expand Down
7 changes: 4 additions & 3 deletions monitoring/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,10 +254,11 @@ By default, the components are deployed into the namespace `monitoring`.

## Access Monitoring Applications

NodePorts are used by default. If you deployed using NodePorts, the monitoring
applications are available at these locations by default:
If the deployment process completes without errors, a message
appears in the console window containing the URL address for Grafana. The URL for Grafana is different depending on whether you use nodeports or ingress to access Grafana.

NodePorts are used by default. If you deployed using NodePorts, Prometheus and AlertManager are available at these locations by default:

* Grafana - Port 31100 `http://master-node.yourcluster.example.com:31100`
* Prometheus - Port 31090 `http://master-node.yourcluster.example.com:31090`
* AlertManager - Port 31091 `http://master-node.yourcluster.example.com:31091`

Expand Down
35 changes: 35 additions & 0 deletions monitoring/bin/deploy_monitoring_cluster.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

cd "$(dirname $BASH_SOURCE)/../.."
source monitoring/bin/common.sh
source bin/service-url-include.sh

source bin/tls-include.sh
if verify_cert_manager $MON_NS prometheus alertmanager grafana; then
Expand Down Expand Up @@ -201,6 +202,38 @@ done
echo ""
monitoring/bin/deploy_dashboards.sh

set +e
# call function to get HTTP/HTTPS ports from ingress controller
get_ingress_ports

# get URLs for Grafana, Prometheus and AlertManager
gf_url=$(get_service_url $MON_NS v4m-grafana "/" "false")
# pr_url=$(get_url $MON_NS v4m-prometheus "/" "false")
# am_url=$(get_url $MON_NS v4m-alertmanager "/" "false")
set -e

# Print URL to access web apps
log_notice ""
log_notice "================================================================================"
log_notice "== Accessing the monitoring applications =="
log_notice "== =="
log_notice "== ***GRAFANA*** =="
if [ ! -z "$gf_url" ]; then
log_notice "== You can access Grafana via the following URL: =="
log_notice "== $gf_url =="
log_notice "== =="
else
log_notice "== It was not possible to determine the URL needed to access Grafana. Note =="
log_notice "== that this is not necessarily a sign of a problem; it may only reflect an =="
log_notice "== ingress or network access configuration that this script does not handle. =="
log_notice "== =="
fi
log_notice "== Note: These URLs may be incorrect if your ingress and/or other network =="
log_notice "== configuration includes options this script does not handle. =="
log_notice "================================================================================"
log_notice ""
echo ""

log_notice "Successfully deployed components to the [$MON_NS] namespace"
if [ "$showPass" == "true" ]; then
# Find the grafana pod
Expand All @@ -211,3 +244,5 @@ if [ "$showPass" == "true" ]; then
log_notice "Change the password at any time by running (replace password):"
log_notice "kubectl exec -n $MON_NS $grafanaPod -c grafana -- bin/grafana-cli admin reset-admin-password myNewPassword"
fi


6 changes: 3 additions & 3 deletions samples/esmulti/logging/user.env
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,10 @@
# LOG_KB_TLS_ENABLE=false



# Kibana hostname override for Ingress and/or DNS Alias
# Kibana hostname override for Ingress and/or DNS Alias (***DEPRECATED 09MAR21**)
# ------------------------------
# ***** USE OF THIS ENV VAR HAS BEEN DEPRECATED AND SUPPORT *****
# ***** FOR IT WILL BE REMOVED ENTIRELY IN AN UPCOMING RELEASE *****
# NODE_NAME specifies the host used by logging to communicate with Kibana
# The default is a node labeled with node-role.kubernetes.io/master
# followed by the first node returned by 'kubectl get nodes'
Expand All @@ -60,7 +61,6 @@
# NODE_NAME=mynode.example.com



# Retention Period Settings
# ------------------------------
# Number of Days to retain log messages
Expand Down
4 changes: 3 additions & 1 deletion samples/generic-base/logging/user.env
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,10 @@



# Kibana hostname override for Ingress and/or DNS Alias
# Kibana hostname override for Ingress and/or DNS Alias (***DEPRECATED 09MAR21**)
# ------------------------------
# ***** USE OF THIS ENV VAR HAS BEEN DEPRECATED AND SUPPORT *****
# ***** FOR IT WILL BE REMOVED ENTIRELY IN AN UPCOMING RELEASE *****
# NODE_NAME specifies the host used by logging to communicate with Kibana
# The default is a node labeled with node-role.kubernetes.io/master
# followed by the first node returned by 'kubectl get nodes'
Expand Down

0 comments on commit f017b38

Please sign in to comment.