diff --git a/dockers/docker-sonic-gnmi/gnmi-native.sh b/dockers/docker-sonic-gnmi/gnmi-native.sh index 8dae895d89d..5b9efe379a2 100755 --- a/dockers/docker-sonic-gnmi/gnmi-native.sh +++ b/dockers/docker-sonic-gnmi/gnmi-native.sh @@ -3,6 +3,11 @@ EXIT_TELEMETRY_VARS_FILE_NOT_FOUND=1 INCORRECT_TELEMETRY_VALUE=2 TELEMETRY_VARS_FILE=/usr/share/sonic/templates/telemetry_vars.j2 +ESCAPE_QUOTE="'\''" + +extract_field() { + echo $(echo $1 | jq -r $2) +} if [ ! -f "$TELEMETRY_VARS_FILE" ]; then echo "Telemetry vars template file not found" @@ -25,30 +30,29 @@ TELEMETRY_ARGS=" -logtostderr" export CVL_SCHEMA_PATH=/usr/sbin/schema if [ -n "$CERTS" ]; then - SERVER_CRT=$(echo $CERTS | jq -r '.server_crt') - SERVER_KEY=$(echo $CERTS | jq -r '.server_key') + SERVER_CRT=$(extract_field "$CERTS" '.server_crt') + SERVER_KEY=$(extract_field "$CERTS" '.server_key') if [ -z $SERVER_CRT ] || [ -z $SERVER_KEY ]; then TELEMETRY_ARGS+=" --insecure" else TELEMETRY_ARGS+=" --server_crt $SERVER_CRT --server_key $SERVER_KEY " fi - CA_CRT=$(echo $CERTS | jq -r '.ca_crt') + CA_CRT=$(extract_field "$CERTS" '.ca_crt') if [ ! -z $CA_CRT ]; then TELEMETRY_ARGS+=" --ca_crt $CA_CRT" fi - TELEMETRY_ARGS+=" --config_table_name GNMI_CLIENT_CERT" elif [ -n "$X509" ]; then - SERVER_CRT=$(echo $X509 | jq -r '.server_crt') - SERVER_KEY=$(echo $X509 | jq -r '.server_key') + SERVER_CRT=$(extract_field "$X509" '.server_crt') + SERVER_KEY=$(extract_field "$X509" '.server_key') if [ -z $SERVER_CRT ] || [ -z $SERVER_KEY ]; then TELEMETRY_ARGS+=" --insecure" else TELEMETRY_ARGS+=" --server_crt $SERVER_CRT --server_key $SERVER_KEY " fi - CA_CRT=$(echo $X509 | jq -r '.ca_crt') + CA_CRT=$(extract_field "$X509" '.ca_crt') if [ ! -z $CA_CRT ]; then TELEMETRY_ARGS+=" --ca_crt $CA_CRT" fi @@ -60,34 +64,27 @@ fi if [ -z "$GNMI" ]; then PORT=8080 else - PORT=$(echo $GNMI | jq -r '.port') + PORT=$(extract_field "$GNMI" '.port') + if ! [[ $PORT =~ ^[0-9]+$ ]]; then + echo "Incorrect port value ${PORT}, expecting positive integers" >&2 + exit $INCORRECT_TELEMETRY_VALUE + fi fi + TELEMETRY_ARGS+=" --port $PORT" -CLIENT_AUTH=$(echo $GNMI | jq -r '.client_auth') +CLIENT_AUTH=$(extract_field "$GNMI" '.client_auth') if [ -z $CLIENT_AUTH ] || [ $CLIENT_AUTH == "false" ]; then TELEMETRY_ARGS+=" --allow_no_client_auth" fi -LOG_LEVEL=$(echo $GNMI | jq -r '.log_level') +LOG_LEVEL=$(extract_field "$GNMI" '.log_level') if [[ $LOG_LEVEL =~ ^[0-9]+$ ]]; then TELEMETRY_ARGS+=" -v=$LOG_LEVEL" else TELEMETRY_ARGS+=" -v=2" fi -if [ -nz "$GNMI" ]; then - ENABLE_CRL=$(echo $GNMI | jq -r '.enable_crl') - if [ $ENABLE_CRL == "true" ]; then - TELEMETRY_ARGS+=" --enable_crl" - fi - - CRL_EXPIRE_DURATION=$(echo $GNMI | jq -r '.crl_expire_duration') - if [ -n $CRL_EXPIRE_DURATION ]; then - TELEMETRY_ARGS+=" --crl_expire_duration $CRL_EXPIRE_DURATION" - fi -fi - # Enable ZMQ for SmartSwitch LOCALHOST_SUBTYPE=`sonic-db-cli CONFIG_DB hget "DEVICE_METADATA|localhost" "subtype"` if [[ x"${LOCALHOST_SUBTYPE}" == x"SmartSwitch" ]]; then @@ -101,7 +98,7 @@ if [[ x"${MGMT_VRF_ENABLED}" == x"true" ]]; then fi # Server will handle threshold connections consecutively -THRESHOLD_CONNECTIONS=$(echo $GNMI | jq -r '.threshold') +THRESHOLD_CONNECTIONS=$(extract_field "$GNMI" '.threshold') if [[ $THRESHOLD_CONNECTIONS =~ ^[0-9]+$ ]]; then TELEMETRY_ARGS+=" --threshold $THRESHOLD_CONNECTIONS" else @@ -114,7 +111,7 @@ else fi # Close idle connections after certain duration (in seconds) -IDLE_CONN_DURATION=$(echo $GNMI | jq -r '.idle_conn_duration') +IDLE_CONN_DURATION=$(extract_field "$GNMI" '.idle_conn_duration') if [[ $IDLE_CONN_DURATION =~ ^[0-9]+$ ]]; then TELEMETRY_ARGS+=" --idle_conn_duration $IDLE_CONN_DURATION" else @@ -126,4 +123,24 @@ else fi fi +USER_AUTH=$(extract_field "$GNMI" '.user_auth') +if [ ! -z "$USER_AUTH" ] && [ $USER_AUTH != "null" ]; then + TELEMETRY_ARGS+=" --client_auth $USER_AUTH" + + if [ $USER_AUTH == "cert" ]; then + TELEMETRY_ARGS+=" --config_table_name GNMI_CLIENT_CERT" + + ENABLE_CRL=$(echo $GNMI | jq -r '.enable_crl') + if [ $ENABLE_CRL == "true" ]; then + TELEMETRY_ARGS+=" --enable_crl" + fi + + CRL_EXPIRE_DURATION=$(extract_field "$GNMI" '.crl_expire_duration') + if [ ! -z "$CRL_EXPIRE_DURATION" ] && [ $CRL_EXPIRE_DURATION != "null" ]; then + TELEMETRY_ARGS+=" --crl_expire_duration $CRL_EXPIRE_DURATION" + fi + fi +fi + +echo "gnmi args: $TELEMETRY_ARGS" exec /usr/sbin/telemetry ${TELEMETRY_ARGS} diff --git a/dockers/docker-sonic-telemetry/telemetry.sh b/dockers/docker-sonic-telemetry/telemetry.sh index 2428922b57f..ad1dcedd156 100755 --- a/dockers/docker-sonic-telemetry/telemetry.sh +++ b/dockers/docker-sonic-telemetry/telemetry.sh @@ -3,6 +3,11 @@ EXIT_TELEMETRY_VARS_FILE_NOT_FOUND=1 INCORRECT_TELEMETRY_VALUE=2 TELEMETRY_VARS_FILE=/usr/share/sonic/templates/telemetry_vars.j2 +ESCAPE_QUOTE="'\''" + +extract_field() { + echo $(echo $1 | jq -r $2) +} if [ ! -f "$TELEMETRY_VARS_FILE" ]; then echo "Telemetry vars template file not found" @@ -25,31 +30,28 @@ export CVL_SCHEMA_PATH=/usr/sbin/schema export GOTRACEBACK=crash if [ -n "$CERTS" ]; then - SERVER_CRT=$(echo $CERTS | jq -r '.server_crt') - SERVER_KEY=$(echo $CERTS | jq -r '.server_key') + SERVER_CRT=$(extract_field "$CERTS" '.server_crt') + SERVER_KEY=$(extract_field "$CERTS" '.server_key') if [ -z $SERVER_CRT ] || [ -z $SERVER_KEY ]; then TELEMETRY_ARGS+=" --insecure" else TELEMETRY_ARGS+=" --server_crt $SERVER_CRT --server_key $SERVER_KEY " fi - CA_CRT=$(echo $CERTS | jq -r '.ca_crt') + CA_CRT=$(extract_field "$CERTS" '.ca_crt') if [ ! -z $CA_CRT ]; then TELEMETRY_ARGS+=" --ca_crt $CA_CRT" fi - - # Reuse GNMI_CLIENT_CERT for telemetry service - TELEMETRY_ARGS+=" --config_table_name GNMI_CLIENT_CERT" elif [ -n "$X509" ]; then - SERVER_CRT=$(echo $X509 | jq -r '.server_crt') - SERVER_KEY=$(echo $X509 | jq -r '.server_key') + SERVER_CRT=$(extract_field "$X509" '.server_crt') + SERVER_KEY=$(extract_field "$X509" '.server_key') if [ -z $SERVER_CRT ] || [ -z $SERVER_KEY ]; then TELEMETRY_ARGS+=" --insecure" else TELEMETRY_ARGS+=" --server_crt $SERVER_CRT --server_key $SERVER_KEY " fi - CA_CRT=$(echo $X509 | jq -r '.ca_crt') + CA_CRT=$(extract_field "$X509" '.ca_crt') if [ ! -z $CA_CRT ]; then TELEMETRY_ARGS+=" --ca_crt $CA_CRT" fi @@ -61,34 +63,26 @@ fi if [ -z "$GNMI" ]; then PORT=8080 else - PORT=$(echo $GNMI | jq -r '.port') + PORT=$(extract_field "$GNMI" '.port') + if ! [[ $PORT =~ ^[0-9]+$ ]]; then + echo "Incorrect port value ${PORT}, expecting positive integers" >&2 + exit $INCORRECT_TELEMETRY_VALUE + fi fi TELEMETRY_ARGS+=" --port $PORT" -CLIENT_AUTH=$(echo $GNMI | jq -r '.client_auth') +CLIENT_AUTH=$(extract_field "$GNMI" '.client_auth') if [ -z $CLIENT_AUTH ] || [ $CLIENT_AUTH == "false" ]; then TELEMETRY_ARGS+=" --allow_no_client_auth" fi -LOG_LEVEL=$(echo $GNMI | jq -r '.log_level') +LOG_LEVEL=$(extract_field "$GNMI" '.log_level') if [[ $LOG_LEVEL =~ ^[0-9]+$ ]]; then TELEMETRY_ARGS+=" -v=$LOG_LEVEL" else TELEMETRY_ARGS+=" -v=2" fi -if [ -nz "$GNMI" ]; then - ENABLE_CRL=$(echo $GNMI | jq -r '.enable_crl') - if [ $ENABLE_CRL == "true" ]; then - TELEMETRY_ARGS+=" --enable_crl" - fi - - CRL_EXPIRE_DURATION=$(echo $GNMI | jq -r '.crl_expire_duration') - if [ -n $CRL_EXPIRE_DURATION ]; then - TELEMETRY_ARGS+=" --crl_expire_duration $CRL_EXPIRE_DURATION" - fi -fi - # gNMI save-on-set behavior is disabled by default. # Save-on-set can be turned on by setting the "TELEMETRY|gnmi|save_on_set" # to "true". @@ -98,7 +92,7 @@ if [ ! -z "$SAVE_ON_SET" ]; then fi # Server will handle threshold connections consecutively -THRESHOLD_CONNECTIONS=$(echo $GNMI | jq -r '.threshold') +THRESHOLD_CONNECTIONS=$(extract_field "$GNMI" '.threshold') if [[ $THRESHOLD_CONNECTIONS =~ ^[0-9]+$ ]]; then TELEMETRY_ARGS+=" --threshold $THRESHOLD_CONNECTIONS" else @@ -111,7 +105,7 @@ else fi # Close idle connections after certain duration (in seconds) -IDLE_CONN_DURATION=$(echo $GNMI | jq -r '.idle_conn_duration') +IDLE_CONN_DURATION=$(extract_field "$GNMI" '.idle_conn_duration') if [[ $IDLE_CONN_DURATION =~ ^[0-9]+$ ]]; then TELEMETRY_ARGS+=" --idle_conn_duration $IDLE_CONN_DURATION" else @@ -124,4 +118,25 @@ else fi TELEMETRY_ARGS+=" -gnmi_native_write=false" +USER_AUTH=$(extract_field "$GNMI" '.user_auth') +if [ ! -z "$USER_AUTH" ] && [ $USER_AUTH != "null" ]; then + TELEMETRY_ARGS+=" --client_auth $USER_AUTH" + + if [ $USER_AUTH == "cert" ]; then + # Reuse GNMI_CLIENT_CERT for telemetry service + TELEMETRY_ARGS+=" --config_table_name GNMI_CLIENT_CERT" + + ENABLE_CRL=$(echo $GNMI | jq -r '.enable_crl') + if [ $ENABLE_CRL == "true" ]; then + TELEMETRY_ARGS+=" --enable_crl" + fi + + CRL_EXPIRE_DURATION=$(extract_field "$GNMI" '.crl_expire_duration') + if [ ! -z "$CRL_EXPIRE_DURATION" ] && [ $CRL_EXPIRE_DURATION != "null" ]; then + TELEMETRY_ARGS+=" --crl_expire_duration $CRL_EXPIRE_DURATION" + fi + fi +fi + +echo "telemetry args: $TELEMETRY_ARGS" exec /usr/sbin/telemetry ${TELEMETRY_ARGS} diff --git a/src/sonic-yang-models/yang-models/sonic-gnmi.yang b/src/sonic-yang-models/yang-models/sonic-gnmi.yang index d33ea35083d..389bac7a125 100644 --- a/src/sonic-yang-models/yang-models/sonic-gnmi.yang +++ b/src/sonic-yang-models/yang-models/sonic-gnmi.yang @@ -85,6 +85,13 @@ module sonic-gnmi { type uint32; description "Certificate revocation list cache expire duration."; } + + leaf user_auth { + type string { + pattern 'password|jwt|cert'; + } + description "GNMI service user authorization type."; + } } } @@ -92,7 +99,6 @@ module sonic-gnmi { description "GNMI client cert list"; list GNMI_CLIENT_CERT_LIST { - max-elements 8; key "cert_cname"; leaf cert_cname { diff --git a/src/sonic-yang-models/yang-models/sonic-telemetry.yang b/src/sonic-yang-models/yang-models/sonic-telemetry.yang index 239f23666dd..825fde053ca 100644 --- a/src/sonic-yang-models/yang-models/sonic-telemetry.yang +++ b/src/sonic-yang-models/yang-models/sonic-telemetry.yang @@ -85,6 +85,13 @@ module sonic-telemetry { type uint32; description "Certificate revocation list cache expire duration."; } + + leaf user_auth { + type string { + pattern 'password|jwt|cert'; + } + description "Telemetry service user authorization type."; + } } }