Class ::nsmcp::ConfigurationTool (public)

 ::nx::Class ::nsmcp::ConfigurationTool[i]

Defined in /usr/local/ns/tcl/nsmcp/lib/config-tools.tcl

Testcases:
No testcase defined.
Source code:
    :property {name configuration}
    :property {permission diagnostics.runtime.read}
    :property redactor:required
    :property authorizer:required
    :property {description {Inspect live NaviServer configuration for configuration reviews, SMTP policy interpretation and scaling advice. scope=server (default) returns process-wide sections plus the authenticated virtual server's sections, excluding other virtual servers. scope=process returns every section across all virtual servers and requires diagnostics.configuration.process.read in addition to diagnostics.runtime.read. Includes driver, database-pool, connection-pool, limit, logging and module settings. Policy scripts are returned as data and are never executed. Named credential values and URI userinfo are redacted; referenced files are not read. Configuration reflects the current configuration table, including defaults published there by modules, not necessarily every compiled default or a historical policy. Use section to select an exact section and its descendants. Follow nextArguments to retrieve remaining sections. Pair with server_topology and server_runtime for actual installed components and utilization.}}
    :property {inputSchema {{} object {type string object properties object {
        scope object {type string string enum array {0 string server 1 string process} default string server}
        section object {type string string description string {Exact section prefix, including descendants; defaults to all authorized sections.}}
        limit object {type string integer minimum number 1 maximum number 100 default number 50}
        offset object {type string integer minimum number 0 default number 0}
    } additionalProperties boolean false}}}

    :method options {arguments} {
        if {[lindex $arguments 1] ne "object"} {error "Expected arguments object"}
        set result {scope server section {} limit 50 offset 0}
        foreach {key type value} [lindex $arguments 2] {
            switch -- $key {
                scope {
                    if {$type ne "string" || $value ni {server process}} {error "scope must be server or process"}
                }
                section {
                    if {$type ne "string" || [string length $value] > 512 || [regexp {[\x00\r\n]} $value]} {error "Invalid configuration section"}
                    set value [string trimright $value /]
                }
                limit - offset {
                    if {$type ne "number" || ![string is integer -strict $value] || $value < 0
                        || ($key eq "limit" && ($value < 1 || $value > 100))} {error "Invalid $key"}
                }
                default {error "Unknown argument: $key"}
            }
            dict set result $key $value
        }
        return $result
    }
    :public method validate {arguments} {
        if {[catch {:options $arguments} message]} {
            return -code error -errorcode {NSMCP RPC -32602} $message
        }
    }
    :method sections {} {
        set sections {}
        foreach handle [ns_configsections] {
            dict set sections [ns_set name $handle] [ns_set array $handle]
        }
        return $sections
    }
    :method credentialParameter {name} {
        return [regexp -nocase {(password|passwd|secret|token|credential|authorization|cookie|private[-_]?key)} $name]
    }
    :method value {name value secrets} {
        if {[:credentialParameter $name]} {return {[REDACTED]}}
        # Remove URI userinfo even for relay/datasource parameters and scripts.
        regsub -all {://[^/\s@]+@} $value {://[REDACTED]@} value
        # Database connection strings can carry credentials inside a datasource.
        regsub -all -nocase {(\m(?:password|passwd|secret|token|credential|authorization)\s*=\s*)(?:'[^']*'|"[^"]*"|[^\s;]+)} $value {\1[REDACTED]} value
        foreach secret $secrets {
            if {$value eq $secret} {return {[REDACTED]}}
            if {[string length $secret] >= 4} {
                set value [string map [list $secret {[REDACTED]}] $value]
            }
        }
        return [${:redactor} message $value]
    }
    :public method execute {context arguments} {
        set options [:options $arguments]
        set server [$context server]
        set scope [dict get $options scope]
        if {$scope eq "process"} {
            ${:authorizer} require $context diagnostics.configuration.process.read
        }
        set prefix [dict get $options section]
        set sections [:sections]
        set secrets {}
        dict for {section parameters} $sections {
            foreach {name value} $parameters {
                if {[:credentialParameter $name] && $value ne ""} {lappend secrets $value}
            }
        }
        set names {}
        set excluded 0
        foreach section [lsort [dict keys $sections]] {
            if {$scope eq "server" && [string match ns/server/* $section]
                && $section ne "ns/server/$server" && [string first "ns/server/$server/" $section] != 0} {
                incr excluded
                continue
            }
            if {$prefix ne "" && $section ne $prefix && [string first $prefix/ $section] != 0} continue
            lappend names $section
        }
        set offset [dict get $options offset]
        set limit [dict get $options limit]
        set array {}
        set index 0
        foreach section [lrange $names $offset [expr {$offset+$limit-1}]] {
            set parameters {}
            set parameterIndex 0
            set seen {}
            foreach {name value} [dict get $sections $section] {
                set clean [:value $name $value $secrets]
                set folded [string tolower $name]
                lappend parameters $parameterIndex object [list name string $name value string $clean  redacted boolean [expr {$clean ne $value}] firstOccurrence boolean [expr {$folded ni $seen}]]
                lappend seen $folded
                incr parameterIndex
            }
            set sectionScope [expr {[string first "ns/server/" $section] == 0 ? "server" : "process"}]
            lappend array $index object [list name string $section scope string $sectionScope parameters array $parameters]
            incr index
        }
        set more [expr {$offset+$index < [llength $names]}]
        set next {}
        if {$more} {
            set next [list scope string $scope section string $prefix limit number $limit offset number [expr {$offset+$index}]]
        }
        return [list {} object [list server string $server observedAt number [clock seconds]  scope string $scope configurationFile string [ns_info config]  sectionCount number [llength $names] excludedServerSections number $excluded  sections array $array more boolean $more nextArguments object $next  coverage object {historical boolean false referencedFilesRead boolean false compiledDefaultsComplete boolean false}]]
    }
XQL Not present:
Generic, PostgreSQL, Oracle
[ hide source ] | [ make this the default ]
Show another procedure: