TT#149202 cat: Add new action to concatenate configuration files

This new action concatenates the various configuration files and outputs
the result as YAML. This is useful because they have a determined
ordering, and include optional host specific files that might not be
obvious how to merge.

This will also be the foundation for verifying all the current host
settings against the cfg-schema.

Change-Id: I72a61193f74caf3b2f7a58a47eefad2ed46c973a
mr10.4
Guillem Jover 3 years ago
parent 7575f51538
commit 6c45358677

@ -2,6 +2,7 @@ etc/ngcp-config/ngcpcfg.cfg etc/ngcp-config/
functions/init usr/share/ngcp-ngcpcfg/functions/
functions/logs usr/share/ngcp-ngcpcfg/functions/
functions/main usr/share/ngcp-ngcpcfg/functions/
helper/cat-yml usr/share/ngcp-ngcpcfg/helper/
helper/check-for-mysql usr/share/ngcp-ngcpcfg/helper/
helper/fileformat_version usr/share/ngcp-ngcpcfg/helper/
helper/instance-info usr/share/ngcp-ngcpcfg/helper/
@ -21,6 +22,7 @@ sbin/ngcp-sync-grants usr/sbin/
sbin/ngcpcfg usr/sbin/
scripts/apply usr/share/ngcp-ngcpcfg/scripts/
scripts/build usr/share/ngcp-ngcpcfg/scripts/
scripts/cat usr/share/ngcp-ngcpcfg/scripts/
scripts/check usr/share/ngcp-ngcpcfg/scripts/
scripts/clean usr/share/ngcp-ngcpcfg/scripts/
scripts/commit usr/share/ngcp-ngcpcfg/scripts/

@ -17,6 +17,10 @@ _ngcpcfg()
_filedir
return
;;
cat)
COMPREPLY=( $( compgen -W 'config network constants' -- "$cur" ) )
return
;;
check)
if [[ "$cur" == -* ]]; then
COMPREPLY=( $( compgen -W '--ignore-branch-check --ignore-shared-storage-check' -- "$cur" ) )

@ -331,6 +331,16 @@ meant so the configuration change history (accessible e.g. via 'ngcpcfg log')
provides useful information.
Options for _services_, _build_ and _check_ can be used here too.
**cat** [<config-type>...]::
Concatenates the YAML configuration files, including any local override files
and prints them to standard output.
If no _config-type_ has been specified, then all configuration files found
are used.
Otherwise one or more of *config*, *network* and *constants* can be specified
in any order (they will get ordered properly internally) to specify what
subset of the YAML configuration files to load and output.
**check** [--ignore-branch-check] [--ignore-shared-storage-check] [<config_files_or_directories>|<pattern>]::
Check syntax of YAML files and validate schema before performing any further actions.

@ -0,0 +1,32 @@
#!/usr/bin/perl -CSD
# Purpose: dump yaml configuration files
################################################################################
use strict;
use warnings;
use YAML::XS;
use Hash::Merge qw(merge);
if (@ARGV < 1) {
die 'Error: you did not specify an input file name\n';
}
my $config = {};
my %loaded = ();
foreach my $file (@ARGV) {
next if exists $loaded{$file};
$loaded{$file} = 1;
my $yaml = YAML::XS::LoadFile($file);
my $hm = Hash::Merge->new('RIGHT_PRECEDENT');
$config = $hm->merge($config, $yaml);
}
# YAML::XS::Dump returns raw UTF-8 strings.
binmode \*STDOUT, ':raw';
print YAML::XS::Dump($config);
## END OF FILE #################################################################

@ -52,6 +52,7 @@ usage() {
Actions:
apply [<msg>] a short-cut for build-services-commit
build [<opts>] generate/update configuration files
cat [<types>] print YAML configuration files
check [<path>] validate YAML configuration files
clean [<opts>] clean /etc/ngcp-config folder configs/templates (see available options)
commit [<msg>] commit and record changes (without pushing)
@ -151,6 +152,7 @@ case ${1:-} in
;;
init-shared|\
initialise|\
cat|\
get|\
edit|\
show)

@ -0,0 +1,98 @@
#!/bin/bash
# Purpose: cat the configuration files in YAML format
################################################################################
set -e
set -u
usage() {
cat >&2 <<HELP
Usage: ngcpcfg cat [<option>...] [<config-type>...]
Options:
-?, --help Print this help message.
<config-type> is one of "constants", "config" or "network", will expand to
include any extended auxiliary files.
Example:
ngcpcfg cat
ngcpcfg cat config
ngcpcfg cat constants config network
HELP
}
# support testsuite
FUNCTIONS="${FUNCTIONS:-/usr/share/ngcp-ngcpcfg/functions/}"
HELPER="${HELPER:-/usr/share/ngcp-ngcpcfg/helper/}"
if ! [ -r "${FUNCTIONS}"/main ] ; then
printf "Error: %s/main could not be read. Exiting.\n" "${FUNCTIONS}">&2
exit 1
fi
# shellcheck disable=SC1090
. "${FUNCTIONS}"/main
CONFIG_TYPES=(config network constants)
# Get the list of config types to load.
if [ "${#:-}" -eq 0 ]; then
config_def=true
else
config_def=false
fi
declare -A config_types
for t in "${CONFIG_TYPES[@]}"; do
config_types[$t]=${config_def}
done
while [ -n "${1:-}" ]; do
case "$1" in
constants|config|network)
config_types[$1]=true
shift
;;
--help|-?)
usage
exit 0
;;
*)
echo "Error: unknown config type '$1'" >&2
exit 1
;;
esac
done
declare -a configs_try
if "${config_types[config]}"; then
configs_try+=("${NGCPCTL_CONFIG}")
configs_try+=("${HA_CONFIG}")
configs_try+=("${PAIR_CONFIG}")
configs_try+=("${HOST_CONFIG}")
configs_try+=("${LOCAL_CONFIG}")
fi
if "${config_types[network]}"; then
configs_try+=("${NETWORK_CONFIG}")
fi
if "${config_types[config]}"; then
configs_try+=("${EXTRA_CONFIG_FILES[@]}")
fi
if "${config_types[constants]}"; then
configs_try+=("${CONSTANTS_CONFIG}")
fi
declare -a configs
for f in "${configs_try[@]}"; do
if [ -z "$f" ]; then
continue
fi
if [ -r "$f" ]; then
configs+=("$f")
fi
done
# main script
exec "${HELPER}/cat-yml" "${configs[@]}"
## END OF FILE #################################################################

@ -0,0 +1,28 @@
---
cluster_sets:
default_set: default
sets:
- dispatcher_id: '50'
name: default
type: central
general:
ngcp_type: spce
kamailio:
lb:
port: 5060
tests: ~
www_admin:
fees_csv:
element_order:
- destination
- zone
- zone_detail
- onpeak_init_rate
- onpeak_init_interval
- onpeak_follow_rate
- onpeak_follow_interval
- offpeak_init_rate
- offpeak_init_interval
- offpeak_follow_rate
- offpeak_follow_interval
- use_free_time

@ -0,0 +1,37 @@
---
cluster_sets:
default_set: default
sets:
- dispatcher_id: '50'
name: default
type: central
database:
dbhost: localhost
dbport: 3306
general:
ngcp_type: spce
kamailio:
lb:
port: 5060
ossbss:
provisioning:
database:
name: provisioning
pass: hEuxXrzLF43X93ULhoNu
user: soap
tests: ~
www_admin:
fees_csv:
element_order:
- destination
- zone
- zone_detail
- onpeak_init_rate
- onpeak_init_interval
- onpeak_follow_rate
- onpeak_follow_interval
- offpeak_init_rate
- offpeak_init_interval
- offpeak_follow_rate
- offpeak_follow_interval
- use_free_time

@ -0,0 +1,32 @@
---
cluster_sets:
default_set: default
sets:
- dispatcher_id: '50'
name: default
type: central
general:
ngcp_type: sppro
ha:
enabled: yes
kamailio:
lb:
port: 5060
pair:
enabled: yes
tests: ~
www_admin:
fees_csv:
element_order:
- destination
- zone
- zone_detail
- onpeak_init_rate
- onpeak_init_interval
- onpeak_follow_rate
- onpeak_follow_interval
- offpeak_init_rate
- offpeak_init_interval
- offpeak_follow_rate
- offpeak_follow_interval
- use_free_time

@ -5,6 +5,7 @@ cache_dir = /results/.cache/pytest
markers =
apply
build
cat
cmdline
get
status

@ -0,0 +1,86 @@
#!/usr/bin/env py.test-3
import pytest
from fixtures.fs import check_output, check_stdoutput
###############################################################
# ngcpcfg cat
###############################################################
@pytest.mark.cat
def test_cat_action_unknown_config_type(ngcpcfgcli):
out = ngcpcfgcli("cat", "mysterious")
assert "" in out.stdout
assert "Error: unknown config type 'mysterious'" in out.stderr
assert out.returncode == 1
@pytest.mark.cat
def test_cat_action_wrong_get_option(ngcpcfgcli):
out = ngcpcfgcli("cat", "--something")
assert "" in out.stdout
assert "Error: unknown config type '--something'" in out.stderr
assert out.returncode == 1
@pytest.mark.cat
def test_cat_action_missing_file(ngcpcfgcli):
out = ngcpcfgcli("cat", env={"NGCPCTL_CONFIG": "/run/nonexistent-file"})
assert "" in out.stdout
assert (
"Error: Configuration file /run/nonexistent-file does not "
+ "exist (unconfigured?) - exiting."
in out.stderr
)
assert out.returncode == 1
@pytest.mark.cat
def test_cat_action_config(ngcpcfgcli, tmpdir):
out = ngcpcfgcli("cat", "config")
test_file = "fixtures/output/config_cat_config"
check_stdoutput(out.stdout, test_file, tmpdir)
assert "" in out.stderr
assert out.returncode == 0
@pytest.mark.cat
def test_cat_action_config_constants(ngcpcfgcli, tmpdir):
out = ngcpcfgcli("cat", "config", "constants")
test_file = "fixtures/output/config_cat_config_constants"
check_stdoutput(out.stdout, test_file, tmpdir)
assert "" in out.stderr
assert out.returncode == 0
@pytest.mark.cat
def test_cat_action_constants_config(ngcpcfgcli, tmpdir):
out = ngcpcfgcli("cat", "constants", "config")
test_file = "fixtures/output/config_cat_config_constants"
check_stdoutput(out.stdout, test_file, tmpdir)
assert "" in out.stderr
assert out.returncode == 0
@pytest.mark.cat
def test_cat_action_config_pro(ngcpcfgcli, tmpdir):
out = ngcpcfgcli(
"cat",
"config",
env={
"NGCPCFG": "fixtures/ngcpcfg_pro.cfg",
},
)
test_file = "fixtures/output/config_cat_config_pro"
check_stdoutput(out.stdout, test_file, tmpdir)
assert "" in out.stderr
assert out.returncode == 0
Loading…
Cancel
Save