You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1991 lines
76 KiB
1991 lines
76 KiB
# -*- tcl -*- |
|
# Maintenance Instruction: leave the 999999.xxx.x as is and use punkshell 'dev make' or bin/punkmake to update from <pkg>-buildversion.txt |
|
# module template: shellspy/src/decktemplates/vendor/punk/modules/template_module-0.0.3.tm |
|
# |
|
# Please consider using a BSD or MIT style license for greatest compatibility with the Tcl ecosystem. |
|
# Code using preferred Tcl licenses can be eligible for inclusion in Tcllib, Tklib and the punk package repository. |
|
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
|
# (C) 2025 |
|
# |
|
# @@ Meta Begin |
|
# Application punk::netbox 999999.0a1.0 |
|
# Meta platform tcl |
|
# Meta license MIT |
|
# @@ Meta End |
|
|
|
|
|
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
|
# doctools header |
|
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
|
#*** !doctools |
|
#[manpage_begin shellspy_module_punk::netbox 0 999999.0a1.0] |
|
#[copyright "2025"] |
|
#[titledesc {Module API}] [comment {-- Name section and table of contents description --}] |
|
#[moddesc {-}] [comment {-- Description at end of page heading --}] |
|
#[require punk::netbox] |
|
#[keywords module] |
|
#[description] |
|
#[para] - |
|
|
|
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
|
|
|
#*** !doctools |
|
#[section Overview] |
|
#[para] overview of punk::netbox |
|
#[subsection Concepts] |
|
#[para] - |
|
|
|
|
|
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
|
## Requirements |
|
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
|
|
|
#*** !doctools |
|
#[subsection dependencies] |
|
#[para] packages used by punk::netbox |
|
#[list_begin itemized] |
|
|
|
package require Tcl 8.6- |
|
package require http |
|
package require rest |
|
package require punk::args |
|
#*** !doctools |
|
#[item] [package {Tcl 8.6}] |
|
#[item] [package {http}] |
|
|
|
# #package require frobz |
|
# #*** !doctools |
|
# #[item] [package {frobz}] |
|
|
|
#*** !doctools |
|
#[list_end] |
|
|
|
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
|
|
|
#*** !doctools |
|
#[section API] |
|
|
|
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
|
# oo::class namespace |
|
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
|
#tcl::namespace::eval punk::netbox::class { |
|
#*** !doctools |
|
#[subsection {Namespace punk::netbox::class}] |
|
#[para] class definitions |
|
#if {[tcl::info::commands [tcl::namespace::current]::interface_sample1] eq ""} { |
|
#*** !doctools |
|
#[list_begin enumerated] |
|
|
|
# oo::class create interface_sample1 { |
|
# #*** !doctools |
|
# #[enum] CLASS [class interface_sample1] |
|
# #[list_begin definitions] |
|
|
|
# method test {arg1} { |
|
# #*** !doctools |
|
# #[call class::interface_sample1 [method test] [arg arg1]] |
|
# #[para] test method |
|
# puts "test: $arg1" |
|
# } |
|
|
|
# #*** !doctools |
|
# #[list_end] [comment {-- end definitions interface_sample1}] |
|
# } |
|
|
|
#*** !doctools |
|
#[list_end] [comment {--- end class enumeration ---}] |
|
#} |
|
#} |
|
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
|
|
|
tcl::namespace::eval punk::netbox {} |
|
|
|
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
|
#*** !doctools |
|
#[section Internal] |
|
tcl::namespace::eval punk::netbox::system { |
|
#*** !doctools |
|
#[subsection {Namespace punk::netbox::system}] |
|
#[para] Internal functions that are not part of the API |
|
|
|
tcl::namespace::export {[a-z]*} ;# Convention: export all lowercase |
|
|
|
punk::args::define { |
|
@id -id ::punk::netbox::system::make_rest_func |
|
@leaders -min 2 -max 2 |
|
commandname -help\ |
|
"Fully qualified commandname. |
|
There must be an existing punk::args definition with @id |
|
directive -id matching the name" |
|
endpoint -help\ |
|
"The subpath to be appended to the base url. |
|
e.g api/ipam/ip-addresses/ |
|
api/ipam/ip-addresses/{id}/" |
|
-verb -default get -choices {get post patch head put delete} |
|
-body -default optional -choicecolumns 2 -choices {none optional required mime_multipart}\ |
|
-choicelabels { |
|
none\ |
|
" The call has no request body, |
|
none must be supplied." |
|
optional\ |
|
" A request body can be supplied, |
|
but is not required" |
|
required\ |
|
" A request body must be supplied." |
|
mime_multipart\ |
|
" A request body must be supplied |
|
and will be interpreted as each |
|
argument representing one part of |
|
a mime/multipart document. Arguments |
|
must be lists containing 2 elements, |
|
a list of header keys and values, |
|
and the mime part body, in this order." |
|
} |
|
} |
|
|
|
#A somewhat sanitized config for outputting to stderr etc |
|
#Obscure at least full Authorization Token |
|
#todo - other headers? |
|
proc obscured_config {cfg} { |
|
set sanconfig $cfg |
|
if {[dict exists $cfg headers]} { |
|
set hdrs [dict get $cfg headers] |
|
if {[dict exists $hdrs Authorization]} { |
|
set auth [dict get $hdrs Authorization] |
|
if {[dict exists $auth Token]} { |
|
dict set auth Token "[string range [dict get $auth Token] 0 5]..." |
|
dict set hdrs Authorization $auth |
|
dict set sanconfig headers $hdrs |
|
} |
|
} |
|
} |
|
return $sanconfig |
|
} |
|
proc make_rest_func {args} { |
|
set argd [punk::args::parse $args withid ::punk::netbox::system::make_rest_func] |
|
lassign [dict values $argd] leaders opts values received |
|
|
|
set commandname [dict get $leaders commandname] |
|
set endpoint [dict get $leaders endpoint] |
|
set verb [dict get $opts -verb] |
|
set body [dict get $opts -body] |
|
|
|
set custom [dict create\ |
|
%commandname% $commandname\ |
|
%endpoint% $endpoint\ |
|
%verb% $verb\ |
|
%body% $body\ |
|
%showpagedict% {!@@results @@results/@*/@*.@*}\ |
|
%showpagedict2% {@@results/@*/@*.@* !@@results}\ |
|
%showdict% {*}\ |
|
%showdict2% {*/*}\ |
|
%showlistofdicts% {@*/@*.@*}\ |
|
] |
|
if {$commandname eq "::punk::netbox::status"} { |
|
#we get duplicate django-version for %showdict% - todo - something. |
|
dict set custom %showdict% {@@django-version @@installed-apps/@*.@* !@@installed-apps} |
|
dict set custom %showdict2% {@@installed-apps/@*.@* !@@installed-apps} |
|
} |
|
|
|
set procbody [string map $custom { |
|
set argd [punk::args::parse $args withid %commandname%] |
|
lassign [dict values $argd] leaders opts values received solos multis |
|
set apicontextid [dict get $leaders apicontextid] |
|
if {[dict exists $received -RETURN]} { |
|
set returntype [dict get $opts -RETURN] |
|
} else { |
|
if {[dict exists $opts -RETURN]} { |
|
#not received - but has default |
|
set returntype [dict get $opts -RETURN] |
|
} else { |
|
#fallback if -RETURN was defined without a default or was omitted |
|
set returntype dict |
|
} |
|
} |
|
|
|
set FORCE 1 |
|
if {[dict exists $opts -FORCE]} { |
|
set FORCE [dict get $opts -FORCE] |
|
} |
|
|
|
set query [list] ;#use list not dict - allows repeated params |
|
dict for {k val} $opts { |
|
switch -- $k { |
|
-CUSTOM_PARAM { |
|
#'-multiple true' |
|
foreach kv $val { |
|
lassign $kv paramname value |
|
lappend query $paramname $value |
|
} |
|
} |
|
-RETURN { |
|
#ignore - already handled |
|
} |
|
default { |
|
if {[string match *_FILTER $k]} { |
|
#all _FILTER methods are '-multiple true' - so are present in $opts as a single key with a value that is a list |
|
#e.g -X_Y_FILTER "blah" |
|
set parts [split $k _] |
|
set name1 [string range [string tolower [lindex $parts 0]] 1 end] ;#strip leading dash off first part |
|
set nametail [string tolower [lrange $parts 1 end-1]] |
|
set paramname [join [list $name1 {*}$nametail] _] |
|
foreach fv $val { |
|
lassign $fv filter value ;#filter is n,gte,lte etc |
|
lappend query ${paramname}__$filter $value |
|
} |
|
} else { |
|
set paramname [string range $k 1 end] |
|
if {$paramname in $multis} { |
|
foreach v $val { |
|
lappend query $paramname $v |
|
} |
|
} else { |
|
lappend query $paramname $val |
|
} |
|
} |
|
} |
|
} |
|
|
|
} |
|
set body %body% |
|
switch -- $body { |
|
required { |
|
set requestbody [dict get $values body] |
|
} |
|
optional { |
|
if {[dict exists $received body]} { |
|
set requestbody [dict get $values body] |
|
} else { |
|
set requestbody "" |
|
} |
|
} |
|
} |
|
upvar ::punk::netbox::contexts contexts |
|
if {![dict exists $contexts $apicontextid]} { |
|
error "specified contextid '$apicontextid' not found" |
|
} |
|
set config [dict create\ |
|
format json\ |
|
result json\ |
|
] |
|
#rest api documentation is unclear on 'result' field |
|
#note our default: result json |
|
#this actually converts the json to a dict |
|
|
|
|
|
dict set config headers [list Authorization [list Token [dict get $contexts $apicontextid token value]]] |
|
if {$returntype in "json jsondump"} { |
|
#if we set result json - we get a dict instead of json :/ |
|
dict set config result raw |
|
} |
|
if {$body in {required optional}} { |
|
#content type for the request data |
|
dict set config headers content-type "application/json" |
|
} |
|
|
|
#variable headerdict |
|
#set config [dict create\ |
|
# headers $headerdict\ |
|
#] |
|
|
|
set url [dict get $contexts $apicontextid url value] |
|
set endpoint "%endpoint%" |
|
if {[string first {{id}} $endpoint] != -1} { |
|
set id [dict get $values id] |
|
set endpoint [string map [list {{id}} $id] $endpoint] |
|
} |
|
#todo - only show if debug (and obscure Authorization Token) |
|
set sanconfig [punk::netbox::system::obscured_config $config] |
|
puts stderr "url:${url}$endpoint query:'$query' verb:%verb% config:'$sanconfig'" |
|
if {$FORCE} { |
|
#FORCE is true for most operations (and no -FORCE option even available) but the option exists and defaults to false for specifically unsafe |
|
#e.g delete operations on entire endpoints |
|
if {$body in {required optional}} { |
|
set result [::rest::%verb% ${url}$endpoint $query $config $requestbody] |
|
} else { |
|
set result [::rest::%verb% ${url}$endpoint $query $config] |
|
} |
|
} else { |
|
puts stderr "%commandname% not called because -FORCE is false" |
|
set sanconfig [punk::netbox::system::obscured_config $config] |
|
puts "url:${url}$endpoint query:'$query' verb:%verb% config:'$sanconfig'" |
|
return |
|
} |
|
switch -exact -- $returntype { |
|
showpagedict { |
|
#return [punk::lib::showdict $result !@@results @@results/@*/@*.@*] |
|
return [punk::lib::showdict $result %showpagedict%] |
|
} |
|
showpagedict2 { |
|
#return [punk::lib::showdict $result @@results/@*/@*.@* !@@results] |
|
return [punk::lib::showdict $result %showpagedict2%] |
|
} |
|
showdict { |
|
return [punk::lib::showdict $result %showdict%] |
|
} |
|
showdict2 { |
|
return [punk::lib::showdict $result %showdict2%] |
|
} |
|
showlist { |
|
return [punk::lib::showdict -roottype list $result] |
|
} |
|
showlistofdicts { |
|
return [punk::lib::showdict $result %showlistofdicts%] |
|
} |
|
jsondump { |
|
package require huddle::json |
|
#pretty-print via huddle (inefficient review) |
|
set h [huddle::json::json2huddle parse $result] |
|
return [huddle::jsondump $h] |
|
} |
|
linelist { |
|
set ret "" |
|
foreach r $result { |
|
append ret $r \n |
|
} |
|
return $ret |
|
} |
|
default { |
|
#plain result: (list or dict) or json - the counterintuitive 'result' field set to raw above sets the rest resulting format to json |
|
return $result |
|
} |
|
} |
|
}] |
|
proc $commandname {args} $procbody |
|
} |
|
|
|
} |
|
|
|
tcl::namespace::eval punk::netbox { |
|
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
|
# Base namespace |
|
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
|
#*** !doctools |
|
#[subsection {Namespace punk::netbox}] |
|
#[para] Core API functions for punk::netbox |
|
#[list_begin definitions] |
|
|
|
variable PUNKARGS |
|
|
|
variable has_tls |
|
set has_tls [expr {![catch {package require tls}]}] |
|
|
|
if {$has_tls} { |
|
::http::register https 443 ::tls::socket |
|
} |
|
|
|
variable ipam |
|
|
|
#TEMP - todo |
|
variable headerdict |
|
set headerdict [dict create\ |
|
Authorization "Token af65b993000874eaefeca0fa02b0d86014e48365"\ |
|
] |
|
#temp |
|
variable url https://www.netbox1.intx.com.au/ |
|
|
|
|
|
variable contexts [dict create] |
|
variable context_id 0 |
|
|
|
proc api_context_names {} { |
|
variable contexts |
|
return [dict keys $contexts] |
|
} |
|
|
|
lappend PUNKARGS [list { |
|
@id -id ::punk::netbox::api_contexts |
|
@cmd -name punk::netbox::api_contexts -help\ |
|
"Show in-memory api contexts. |
|
These are named contexts for calling |
|
the NETBOX rest api. |
|
They are loaded using api_contexts_load from |
|
a .toml configuration file, or created using |
|
api_context_create." |
|
-return -default table -choices {table tableobject dict} |
|
-fields -type list -default {url tokentail comment} -choices {url token tokentail comment *} -choicemultiple {0 -1} -choicerestricted 0 -help\ |
|
"The * token can be included in the list of specified |
|
fields, and represents any other available fields found |
|
from the matched contexts" |
|
@values -min 0 -max 1 |
|
globname -default * -help\ |
|
"pattern to match the context name(s)" |
|
}] |
|
proc api_contexts {args} { |
|
set argd [punk::args::parse $args withid ::punk::netbox::api_contexts] |
|
lassign [dict values $argd] leaders opts values received |
|
set returntype [dict get $opts -return] |
|
set fields [dict get $opts -fields] |
|
set globname [dict get $values globname] |
|
|
|
|
|
variable contexts |
|
set matches [dict keys $contexts $globname] |
|
|
|
|
|
if {"*" in $fields} { |
|
set starposn [lsearch -exact $fields *] |
|
set before [lrange $fields 0 $starposn-1] |
|
set after [lrange $fields $starposn+1 end] |
|
set allspecified [list {*}$before {*}$after] |
|
# use * as placeholder for all others not specified - retain order of specified columns |
|
set fields [list] |
|
#check fields in all matches |
|
set starfields [list] |
|
if {"tokentail" ni $allspecified} { |
|
#calculated column |
|
lappend starfields tokentail |
|
} |
|
foreach k $matches { |
|
set contextinfo [dict get $contexts $k] |
|
dict for {valkey valinfo} $contextinfo { |
|
if {$valkey ni $allspecified && $valkey ni $starfields} { |
|
lappend starfields $valkey |
|
} |
|
} |
|
} |
|
set fields [list {*}$before {*}$starfields {*}$after] |
|
} |
|
|
|
|
|
switch -- $returntype { |
|
table - tableobject { |
|
package require textblock |
|
set t [textblock::table -return tableobject -minwidth 75 -headers [list contextid {*}$fields]] |
|
foreach k $matches { |
|
set contextinfo [dict get $contexts $k] |
|
set tokentail "" |
|
if {"tokentail" in $fields} { |
|
#computed column |
|
if {[dict exists $contextinfo token]} { |
|
set tokentail [string range [dict get $contextinfo token value] end-5 end] |
|
} |
|
} |
|
set rowdata [list $k] |
|
foreach f $fields { |
|
if {[dict exists $contextinfo $f value]} { |
|
lappend rowdata [dict get $contextinfo $f value] |
|
} else { |
|
if {$f eq "tokentail"} { |
|
lappend rowdata $tokentail |
|
} else { |
|
lappend rowdata "" |
|
} |
|
} |
|
} |
|
$t add_row $rowdata |
|
} |
|
if {$returntype eq "table"} { |
|
set tableview [$t print] |
|
$t destroy |
|
return $tableview |
|
} else { |
|
return $t |
|
} |
|
} |
|
dict { |
|
set result [dict create] |
|
foreach k $matches { |
|
set contextinfo [dict get $contexts $k] |
|
set tokentail "" |
|
if {"tokentail" in $fields} { |
|
#computed column |
|
if {[dict exists $contextinfo token]} { |
|
set tokentail [string range [dict get $contextinfo token value] end-5 end] |
|
} |
|
} |
|
dict set result $k {} ;#ensure record is output even if empty fieldlist |
|
foreach f $fields { |
|
if {[dict exists $contextinfo $f value]} { |
|
dict set result $k $f [dict get $contextinfo $f value] |
|
} else { |
|
if {$f eq "tokentail"} { |
|
dict set result $k tokentail $tokentail |
|
} |
|
} |
|
} |
|
#dict for {valkey valinfo} $contextinfo { |
|
# dict set result $k $valkey [dict get $valinfo value] |
|
#} |
|
} |
|
return $result |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
#get api handle(s) for a netbox server (with url and token) to pass to the punk::netbox api functions |
|
lappend PUNKARGS [list { |
|
@id -id ::punk::netbox::api_context_load |
|
@cmd -name punk::netbox::api_context_load -help\ |
|
"Load API context information (url token) |
|
from a .toml file in the data directory |
|
or from a specified file. |
|
To create an initial file, use api_context |
|
to create one or more named configurations |
|
specifying the url and authentication token. |
|
Then use api_context_save to persist them." |
|
@opts |
|
-contextname -default * -help\ |
|
"Name of an API context or a pattern for |
|
which contexts to load from the file." |
|
@values |
|
filepath -default "" -type file |
|
}] |
|
proc api_context_load {args} { |
|
set argd [punk::args::parse $args withid ::punk::netbox::api_context_load] |
|
lassign [dict values $argd] leaders opts values received |
|
set contextglob [dict get $opts -contextname] |
|
set filepath [dict get $values filepath] |
|
|
|
if {$filepath eq ""} { |
|
set filepath [_datafile] |
|
} |
|
if {![file exists $filepath]} { |
|
error "No existing datafile at '$filepath'\nUse api_context_create to configure a context and save it with api_context_save" |
|
} |
|
package require tomlish |
|
set tomldata [readFile $filepath] |
|
set tomlish [tomlish::from_toml $tomldata] ;#intermediate (unvalidated) representation of toml data - maintaining whitespace and comments |
|
set tomldict [tomlish::to_dict $tomlish] ;#lossy conversion to a programmatic structure (loss is of comments, whitespace) |
|
variable contexts |
|
#merge into any existing-in-memory loaded/created contexts |
|
set loaded [list] |
|
dict for {contextid contextinfo} $tomldict { |
|
if {[string match $contextglob $contextid]} { |
|
if {![dict exists $contextinfo url]} { |
|
puts "api_context_load warning: Loaded context $contextid is missing 'url' key" |
|
} |
|
if {![dict exists $contextinfo token]} { |
|
puts "api_context_load warning: Loaded context $contextid is missing 'token' key" |
|
} |
|
dict set contexts $contextid $contextinfo |
|
lappend loaded $contextid |
|
} |
|
} |
|
return $loaded |
|
} |
|
|
|
lappend PUNKARGS [list { |
|
@id -id ::punk::netbox::api_context_create |
|
@cmd -name punk::netbox::api_context_create -help\ |
|
"Create an in-memory configuration for an API context. |
|
This consists of a name (contextid) under which a |
|
url and authentication token are stored. |
|
It can optionally be persisted using api_context_save |
|
to the file of your choice, or to a reasonable default |
|
location. (see _datafile). |
|
The api_context_load function can be used to retrieve |
|
previously stored contextids instead of calling this |
|
function each time. |
|
|
|
A contextid is required when calling the netbox rest api |
|
functions such as ipam::vrfs |
|
This allows easy intermixing of calls to either the same |
|
or different servers using the different permissions |
|
granted by each token. |
|
" |
|
@leaders -min 1 -max 1 |
|
contextid -type string -help\ |
|
"Name for the api context. |
|
If saved to a .toml file, this |
|
will be the name of a toplevel table |
|
containing configuration elements such |
|
as url and token." |
|
@opts |
|
-property_value -type list -minsize 2 -maxsize 2 -multiple 1 -help\ |
|
"custom property and value. |
|
e.g |
|
property_value {comment {test comment}}" |
|
@values -min 2 -max 2 |
|
url -type string -help\ |
|
"Base url of netbox server" |
|
token -type string -help\ |
|
"Netbox API authentication token" |
|
}] |
|
proc api_context_create {args} { |
|
set argd [punk::args::parse $args withid ::punk::netbox::api_context_create] |
|
lassign [dict values $argd] leaders opts values received |
|
set contextid [dict get $leaders contextid] |
|
if {[dict exists $received -property_value]} { |
|
set propvals [dict get $opts -property_value] ;#multiple - as pairs |
|
} else { |
|
set propvals [list] |
|
} |
|
set baseurl [dict get $values url] |
|
set token [dict get $values token] |
|
|
|
variable contexts |
|
if {[dict exists $contexts $contextid]} { |
|
error "api_context_create a context with id '$contextid' already exists." |
|
} |
|
set allprops [dict create url [dict create type STRING value $baseurl] token [dict create type STRING value $token]] |
|
foreach pv $propvals { |
|
lassign $pv p v |
|
if {$p in {url token}} { |
|
puts stderr "ignoring -property_value $p - invalid - already specified in arguments" |
|
} |
|
#todo - multiline? |
|
dict set allprops $p [dict create type STRING value $v] |
|
} |
|
dict set contexts $contextid $allprops |
|
return $contextid |
|
} |
|
proc _homedir {} { |
|
if {[info exists ::env(HOME)]} { |
|
set home [file normalize $::env(HOME)] |
|
} else { |
|
#not available on 8.6? ok will error out here. |
|
set home [file tildeexpand ~] |
|
} |
|
return $home |
|
} |
|
lappend PUNKARGS [list { |
|
@id -id ::punk::netbox::_datafile |
|
@cmd -name punk::netbox::_datafile -help\ |
|
"Get the path for the default storage file |
|
used when an explicit path is not given by |
|
the caller to the api_context load/save |
|
functions. This file is in toml format. |
|
|
|
On any platform the XDG_DATA_HOME env var |
|
can be used to override the location, but |
|
on Windows the LOCALAPPDATA env var will |
|
specifiy the location if XDG_DATA_HOME is |
|
not set. |
|
Interfacing with a proper secret store |
|
should be considered as an alternative. |
|
|
|
On non Windows platforms: |
|
The XDG_DATA_HOME env var is the preferred |
|
choice of location - considered slightly more |
|
secure than XDG_CONFIG_HOME. |
|
A folder under the user's home directory, |
|
at .local/share/punk/netbox is chosen if |
|
XDG_DATA_HOME is not configured. |
|
" |
|
@leaders -min 0 -max 0 |
|
@opts |
|
-quiet -type none -help\ |
|
"Suppress warning given when the folder does |
|
not yet exist" |
|
@values -min 0 -max 0 |
|
}] |
|
proc _datafile {args} { |
|
set argd [punk::args::parse $args withid ::punk::netbox::_datafile] |
|
lassign [dict values $argd] leaders opts values received |
|
set be_quiet [dict exists $received -quiet] |
|
|
|
set was_noisy 0 |
|
if {[info exists ::env(XDG_DATA_HOME)]} { |
|
set data_home $::env(XDG_DATA_HOME) |
|
} else { |
|
if {$::tcl_platform(platform) eq "windows"} { |
|
set data_home $::env(LOCALAPPDATA) |
|
} else { |
|
set data_home [file join [_homedir] .local share] |
|
if {!$be_quiet} { |
|
puts stderr "Environment variable XDG_DATA_HOME does not exist - consider setting it if $data_home is not a suitable location" |
|
set was_noisy 1 |
|
} |
|
} |
|
} |
|
if {!$be_quiet && ![file exists $data_home]} { |
|
#parent folder for 'punk' config dir doesn't exist |
|
set msg "configuration location XDG_DATA_HOME or ~/.local/share (or LOCALAPPDATA on windows) at path '$data_home' does not yet exist" |
|
append msg \n " - please create it and/or set the appropriate env var." |
|
puts stderr $msg |
|
set was_noisy 1 |
|
} |
|
set punk_netbox_data_dir [file join $data_home punk netbox] |
|
if {!$be_quiet && ![file exists $punk_netbox_data_dir]} { |
|
set msg "punk::netbox data storage folder at $punk_netbox_data_dir does not yet exist." |
|
append msg \n " It will be created if api_context_save is called without specifying an alternate location." |
|
puts stderr $msg |
|
set was_noisy 1 |
|
} |
|
if {!$be_quiet && $was_noisy} { |
|
puts stderr "punk::netbox::_datafile - call with -quiet option to suppress these messages" |
|
} |
|
return [file join $punk_netbox_data_dir netbox_api_contexts.toml] |
|
} |
|
|
|
lappend PUNKARGS [list { |
|
@id -id ::punk::netbox::api_context_save |
|
@cmd -name punk::netbox::api_context_save -help\ |
|
"" |
|
@values |
|
contextid -type string -help\ |
|
"Name for the api context. |
|
If saved to a .toml file, this |
|
will be the name of a toplevel table |
|
containing configuration elements such |
|
as url and token." |
|
filepath -default "" -optional 1 -type file -help\ |
|
"Path of .toml configuration file containing |
|
API url and token information. |
|
If empty it will store under XDG_DATA_DIR |
|
if the env var is defined, or in the |
|
corresponding location within ~/.local/share. |
|
In both cases the subfolder netbox/punk will |
|
be used. |
|
These locations are fairly reasonable for |
|
sensitive data - but as tokens are not |
|
encrypted, a proper security store should be |
|
used instead if your risk-policy requires |
|
more serious security. |
|
" |
|
}] |
|
proc api_context_save {args} { |
|
set argd [punk::args::parse $args withid ::punk::netbox::api_context_save] |
|
lassign [dict values $argd] leaders opts values received |
|
set contextid [dict get $values contextid] |
|
set filepath [dict get $values filepath] |
|
|
|
variable contexts |
|
if {![dict exists $contexts $contextid]} { |
|
error "punk::netbox::api_context_save error. No context with id '$contextid' exists. Load from file, or create it using punk::netbox::api_context" |
|
} |
|
if {$filepath eq ""} { |
|
set filepath [_datafile -quiet] |
|
set filefolder [file dirname $filepath] |
|
if {![file exists $filefolder]} { |
|
file mkdir $filefolder |
|
} |
|
} |
|
set configdir [file dirname $filepath] |
|
if {![file exists $configdir]} { |
|
error "api_context_save error: folder $configdir doesn't exist" |
|
} |
|
package require tomlish |
|
if {[file exists $filepath]} { |
|
set existing_toml [readFile $filepath] |
|
set tomlish [tomlish::from_toml $existing_toml] |
|
set data_dict [tomlish::to_dict $tomlish] |
|
if [dict exists $data_dict $contextid] { |
|
#todo - nondestructive merge - don't destroy comments/formatting of existing records |
|
#if we use to_dict on the existing tomlish - we lose comments etc |
|
#also from_dict doesn't yet produce canonical nice-for-humans tomlish/toml |
|
#merge |
|
puts stderr "contextid '$contextid' exists in file $filepath" |
|
puts stderr "Merge not implemented.." |
|
set newfiledata "" |
|
} else { |
|
#append to existing toml data |
|
set newdict [dict create $contextid [dict get $contexts $contextid]] |
|
#we store our contexts in a structure already suitable for toml |
|
# (ie one where we tag strings,ints e.g {type STRING value "etc"}) |
|
set newtomlish [tomlish::from_dict $newdict] |
|
set newtoml [tomlish::to_toml $newtomlish] |
|
set newfiledata $existing_toml\n$newtoml |
|
} |
|
} else { |
|
set newdict [dict create $contextid [dict get $contexts $contextid]] |
|
set newtomlish [tomlish::from_dict $newdict] |
|
set newtoml [tomlish::to_toml $newtomlish] |
|
set newfiledata $newtoml |
|
} |
|
|
|
if {$newfiledata ne ""} { |
|
writeFile $filepath $newfiledata |
|
puts stderr "saved [string length $newfiledata] bytes to '$filepath'" |
|
} |
|
} |
|
|
|
|
|
namespace eval argdoc { |
|
set _page_options { |
|
-limit -default 100 -type integer -help\ |
|
"Each REST query returns a maximum number |
|
of results. This can be set to 0 to mean |
|
no limit - but it is still restricted to |
|
the max configured on the server. (1000?) |
|
|
|
This is effectively the page-size of the |
|
results. To retrieve more than a page, the |
|
next and previous urls can be iterated over." |
|
-offset -default 0 -type integer |
|
} |
|
set _create_update_options { |
|
-created |
|
-created__gte |
|
-created__lte |
|
-last_updated |
|
-last_updated__gte |
|
-last_updated__lte |
|
} |
|
set _tenant_options { |
|
-tenant_group_id |
|
-tenant_group_id__n |
|
-tenant_group |
|
-tenant_group__n |
|
-tenant_id |
|
-tenant_id__n |
|
-tenant |
|
-tenant__n |
|
} |
|
set _region_options { |
|
-region_id |
|
-region |
|
} |
|
set _site_options { |
|
-site_group_id |
|
-site_group_id__n |
|
-site_group |
|
-site_group__n |
|
-site_id |
|
-site_id__n |
|
-site |
|
-site__n |
|
} |
|
set _group_options { |
|
-group_id |
|
-group_id__n |
|
-group |
|
-group__n |
|
} |
|
set _contact_options { |
|
-contact |
|
-contact__n |
|
-contact_role |
|
-contact_role__n |
|
-contact_group |
|
-contact_group__n |
|
} |
|
set _role_options { |
|
-role_id |
|
-role_id__n |
|
-role |
|
-role__n |
|
} |
|
set _filter_string [list\ |
|
"ie <str>\n Exact match\n(case-insensitive)"\ |
|
"nie <str>\n Inverse exact match\n(case-insensitive)"\ |
|
"n <str>\n Not equal to"\ |
|
"ic <str>\n Contains\n (case-insensitive)"\ |
|
"nic <str>\n Does not contain\n (case-insensitive)"\ |
|
"isw <str>\n Starts with\n (case-insensitive)"\ |
|
"nisw <str>\n Does not start with\n (case-insensitive)"\ |
|
"iew <str>\n Ends with\n (case-insensitive)"\ |
|
"niew <str>\n Does not end with\n (case-insensitive)"\ |
|
"empty <bool>\n Is empty/null"\ |
|
] |
|
set _filter_number [list\ |
|
"n <num>\n Not equal to"\ |
|
"lte <num>\n Less than or equal"\ |
|
"lt <num>\n Less than"\ |
|
"gte <num>\n Greater than or equal"\ |
|
"gt <num>\n Greater than"\ |
|
] |
|
set _CUSTOM_PARAMS { |
|
-CUSTOM_PARAM -type list -minsize 2 -maxsize 2 -multiple 1 -help\ |
|
"Specify a parameter not in this API |
|
e.g -CUSTOM_PARAM {mytag blah}" |
|
} |
|
set _RETURN_PAGEDICT { |
|
-RETURN -type string -choices {dict showpagedict showpagedict2 json jsondump} -choicelabels { |
|
dict\ |
|
" Tcl dictionary |
|
(fastest)" |
|
showpagedict\ |
|
" human readable dict display |
|
with same order as dict." |
|
showpagedict2\ |
|
" human readable dict display |
|
results first, page metadata last." |
|
} -help\ |
|
"Options for returned data. |
|
Note that showdict results are relatively slow, especially for large resultsets" |
|
} |
|
set _RETURN_DICT { |
|
-RETURN -type string -choices {dict showdict showdict2 json jsondump} -choicelabels { |
|
dict\ |
|
" Tcl dictionary |
|
(fastest)" |
|
showdict\ |
|
" human readable dict display |
|
with same order as dict." |
|
showdict2\ |
|
" human readable dict display |
|
results first metadata last." |
|
} -help\ |
|
"Options for returned data. |
|
Note that showdict results are relatively slow, especially for large resultsets" |
|
} |
|
set _RETURN_LIST { |
|
-RETURN -type string -choices {list linelist showlist json jsondump} -choicelabels { |
|
list\ |
|
" Tcl list |
|
(fastest)" |
|
linelist\ |
|
" raw list with newline after each item" |
|
showlist\ |
|
" human readable list display" |
|
} -help\ |
|
"Options for returned data. |
|
Note that showlist results are relatively slow, especially for large resultsets" |
|
} |
|
set _RETURN_LISTOFDICTS { |
|
-RETURN -type string -choices {list linelist showlist json jsondump} -choicelabels { |
|
list\ |
|
" Tcl list |
|
(fastest)" |
|
linelist\ |
|
" raw list with newline after each item" |
|
showlistofdicts\ |
|
" human readable display list of dicts" |
|
} -help\ |
|
"Options for returned data. |
|
Note that showlist results are relatively slow, especially for large resultsets" |
|
} |
|
set _RETURN_STATUS { |
|
-RETURN -type string -default showdict2 -choices {dict showdict showdict2 json jsondump} -choicelabels { |
|
dict\ |
|
" Tcl dictionary" |
|
showdict\ |
|
" human readable dict display" |
|
showdict2\ |
|
" human readable dict display |
|
installed-apps first." |
|
} -help\ |
|
"Options for returned data." |
|
} |
|
|
|
set _name_filter_help "Paired search filter for name:\n" |
|
append _name_filter_help [textblock::list_as_table -columns 4 -show_hseps 1 $_filter_string] |
|
|
|
set _description_filter_help "Paired search filter for description:\n" |
|
append _description_filter_help [textblock::list_as_table -columns 4 -show_hseps 1 $_filter_string] |
|
|
|
set string_filter_help "Paired search filter for string:\n" |
|
append _string_filter_help [textblock::list_as_table -columns 4 -show_hseps 1 $_filter_string] |
|
|
|
#n, lte, lt, gte, gt |
|
#e.g virtualization/virtual-machine vcpus, memory, disk |
|
set number_filter_help "Paired search filter for number:\n" |
|
append _number_filter_help [textblock::list_as_table -columns 3 -show_hseps 1 $_filter_number] |
|
} |
|
|
|
punk::args::define {*}[list\ |
|
{ |
|
@dynamic |
|
@id -id ::punk::netbox::status |
|
@cmd -name punk::netbox::status -help\ |
|
"status_list |
|
GET request for endpoint /status/ |
|
|
|
Netbox's current operational status |
|
" |
|
@leaders -min 1 -max 1 |
|
apicontextid -help\ |
|
"The name of the stored api context to use. |
|
A contextid can be created in-memory using |
|
api_context_create, or loaded from a .toml |
|
file using api_context_load."\ |
|
-choices {${[punk::netbox::api_context_names]}} |
|
@opts |
|
}\ |
|
[set ::punk::netbox::argdoc::_RETURN_STATUS]\ |
|
{ |
|
@values -min 0 -max 0 |
|
}] |
|
::punk::netbox::system::make_rest_func ::punk::netbox::status api/status/ -verb get -body none |
|
|
|
|
|
#test function - todo use punk::netbox::system::make_rest_func |
|
#proc vrfs {args} { |
|
# set argd [punk::args::parse $args withid ::punk::netbox::vrfs] |
|
# lassign [dict values $argd] leaders opts values received |
|
# set apicontextid [dict get $leaders apicontextid] |
|
# set query [dict create] |
|
# dict for {k v} $opts { |
|
# if {$k eq "-CUSTOM_PARAM"} { |
|
# foreach custval $v { |
|
# lassign $custval param value |
|
# dict set query $param $value |
|
# } |
|
# } elseif {[string match *_FILTER $k]} { |
|
# set field [string range [string tolower [lindex [split $k _] 0]] 1 end] ;# -NAME_FILTER -> name |
|
# foreach fv $v { |
|
# lassign $fv filter value |
|
# dict set query ${field}__$filter $value |
|
# } |
|
# } else { |
|
# dict set query [string range $k 1 end] $v |
|
# } |
|
# } |
|
# variable contexts |
|
# if {![dict exists $contexts $apicontextid]} { |
|
# error "specified contextid '$apicontextid' not found" |
|
# } |
|
# set config [dict create\ |
|
# result json\ |
|
# ] |
|
# dict set config headers [list Authorization [list Token [dict get $contexts $apicontextid token value]]] |
|
|
|
# #variable headerdict |
|
# #set config [dict create\ |
|
# # headers $headerdict\ |
|
# # result json\ |
|
# #] |
|
# #variable url |
|
# set url [dict get $contexts $apicontextid url value] |
|
|
|
# puts "${url}api/ipam/vrfs/ '$query' '$config'" |
|
# rest::get ${url}api/ipam/vrfs/ $query $config |
|
#} |
|
|
|
#set ipam(vrfs) [dict create\ |
|
# url https://www.netbox1.intx.com.au/api/ipam/vrfs/\ |
|
# method get\ |
|
# result json\ |
|
# body none\ |
|
# headers $headerdict\ |
|
# opt_args {id: name: limit:100 offset:0} |
|
#] |
|
#set ipam(ip-addresses) [dict create\ |
|
# url https://www.netbox1.intx.com.au/api/ipam/ip-addresses/\ |
|
# method get\ |
|
# headers $headerdict\ |
|
# opt_args {parent: limit:100 offset:0} |
|
#] |
|
#set ipam(prefixes) [dict create\ |
|
# url https://www.netbox1.intx.com.au/api/ipam/prefixes/\ |
|
# method get\ |
|
# headers $headerdict\ |
|
# opt_args {prefix: limit:100 offset:0} |
|
#] |
|
#rest::create_interface ::punk::netbox::ipam |
|
|
|
|
|
#proc sample1 {p1 n args} { |
|
# #*** !doctools |
|
# #[call [fun sample1] [arg p1] [arg n] [opt {option value...}]] |
|
# #[para]Description of sample1 |
|
# #[para] Arguments: |
|
# # [list_begin arguments] |
|
# # [arg_def tring p1] A description of string argument p1. |
|
# # [arg_def integer n] A description of integer argument n. |
|
# # [list_end] |
|
# return "ok" |
|
#} |
|
|
|
|
|
|
|
|
|
#*** !doctools |
|
#[list_end] [comment {--- end definitions namespace punk::netbox ---}] |
|
} |
|
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
|
|
|
tcl::namespace::eval punk::netbox::dcim { |
|
namespace export {[a-z]*} |
|
lappend PUNKARGS [list\ |
|
{ |
|
@dynamic |
|
@id -id ::punk::netbox::dcim::devices_list |
|
@cmd -name punk::netbox::dcim::devices_list -help\ |
|
"tenancy_tenants_list |
|
GET request for endpoint /dcim/devices/" |
|
@leaders -min 1 -max 1 |
|
apicontextid -help\ |
|
"The name of the stored api context to use. |
|
A contextid can be created in-memory using |
|
api_context_create, or loaded from a .toml |
|
file using api_context_load."\ |
|
-choices {${[punk::netbox::api_context_names]}} |
|
@opts |
|
-id -type integer |
|
-ID_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -help {${$::punk::netbox::argdoc::_number_filter_help}} |
|
-name |
|
-NAME_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -help {${$::punk::netbox::argdoc::_name_filter_help}} |
|
-asset_tag -type string |
|
-ASSET_TAG_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -help {${$::punk::netbox::argdoc::_string_filter_help}} |
|
-face -type string |
|
-face__n -type string |
|
-position -type integer |
|
-POSITION_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -help {${$::punk::netbox::argdoc::_number_filter_help}} |
|
-airflow -type string |
|
-airflow__n -type string |
|
-vc_position -type integer |
|
-VC_POSITION_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -help {${$::punk::netbox::argdoc::_number_filter_help}} |
|
-vc_priority -type integer |
|
-VC_PRIORITY_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -help {${$::punk::netbox::argdoc::_number_filter_help}} |
|
}\ |
|
[set ::punk::netbox::argdoc::_create_update_options]\ |
|
{ |
|
-q -type string |
|
-tag -type string |
|
-tag__n -type string |
|
}\ |
|
[set ::punk::netbox::argdoc::_tenant_options]\ |
|
[set ::punk::netbox::argdoc::_contact_options]\ |
|
{ |
|
-local_context_data |
|
-manufacturer_id |
|
-manufacturer_id__n |
|
-manufacturer |
|
-manufacturer__n |
|
-device_type_id |
|
-device_type_id__n |
|
-role_id |
|
-role_id__n |
|
-role |
|
-role__n |
|
-parent_device_id |
|
-parent_device_id__n |
|
-platform_id |
|
-platform_id__n |
|
-platform |
|
-platform__n |
|
}\ |
|
[set ::punk::netbox::argdoc::_group_options]\ |
|
[set ::punk::netbox::argdoc::_region_options]\ |
|
[set ::punk::netbox::argdoc::_site_options]\ |
|
{ |
|
-location_id -type integer |
|
-location_id__n -type integer |
|
-rack_id -type integer |
|
-rack_id__n -type integer |
|
-cluster_id -type integer |
|
-cluster_id__n -type integer |
|
-model -type string |
|
-model__n -type string |
|
-status -type string |
|
-status__n -type string |
|
-mac_address -type string |
|
-MAC_ADDRESS_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -help {${$::punk::netbox::argdoc::_string_filter_help}} |
|
-serial -type string |
|
-SERIAL_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -help {${$::punk::netbox::argdoc::_string_filter_help}} |
|
-virtual_chassis_id -type integer |
|
-virtual_chassis_id__n -type integer |
|
}\ |
|
[set ::punk::netbox::argdoc::_page_options]\ |
|
[set ::punk::netbox::argdoc::_CUSTOM_PARAMS]\ |
|
[set ::punk::netbox::argdoc::_RETURN_PAGEDICT]\ |
|
{ |
|
@values -min 0 -max 0 |
|
}] |
|
::punk::netbox::system::make_rest_func ::punk::netbox::dcim::devices_list api/dcim/devices/ -verb get -body none |
|
} |
|
|
|
tcl::namespace::eval punk::netbox::ipam { |
|
namespace export {[a-z]*} |
|
lappend PUNKARGS [list\ |
|
{ |
|
@dynamic |
|
@id -id ::punk::netbox::ipam::vrfs_list |
|
@cmd -name punk::netbox::ipam::vrfs_list -help\ |
|
"ipam_vrfs_list |
|
GET request for endpoint /ipam/vrfs/" |
|
@leaders -min 1 -max 1 |
|
apicontextid -help\ |
|
"The name of the stored api context to use. |
|
A contextid can be created in-memory using |
|
api_context_create, or loaded from a .toml |
|
file using api_context_load."\ |
|
-choices {${[punk::netbox::api_context_names]}} |
|
@opts |
|
-id -type integer |
|
-ID_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -help {${$::punk::netbox::argdoc::_number_filter_help}} |
|
-name |
|
-NAME_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -help {${$::punk::netbox::argdoc::_name_filter_help}} |
|
-rd -type string -help\ |
|
"Route distinguisher in any format" |
|
-enforce_unique |
|
-description -type string -help "Exact Match (case sensitive)" |
|
-DESCRIPTION_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -help {${$::punk::netbox::argdoc::_description_filter_help}} |
|
}\ |
|
[set ::punk::netbox::argdoc::_create_update_options]\ |
|
{ |
|
-q |
|
-tag |
|
}\ |
|
[set ::punk::netbox::argdoc::_tenant_options]\ |
|
[set ::punk::netbox::argdoc::_region_options]\ |
|
[set ::punk::netbox::argdoc::_site_options]\ |
|
[set ::punk::netbox::argdoc::_group_options]\ |
|
[set ::punk::netbox::argdoc::_role_options]\ |
|
{ |
|
-status |
|
-available_on_device |
|
-available_on_virtualmachine |
|
}\ |
|
[set ::punk::netbox::argdoc::_page_options]\ |
|
[set ::punk::netbox::argdoc::_CUSTOM_PARAMS]\ |
|
[set ::punk::netbox::argdoc::_RETURN_PAGEDICT]\ |
|
{ |
|
@values -min 0 -max 0 |
|
}] |
|
::punk::netbox::system::make_rest_func ::punk::netbox::ipam::vrfs_list api/ipam/vrfs/ -verb get -body none |
|
|
|
lappend PUNKARGS [list\ |
|
{ |
|
@dynamic |
|
@id -id ::punk::netbox::ipam::vrfs_read |
|
@cmd -name punk::netbox::ipam::vrfs_read -help\ |
|
"ipam_vrfs_list |
|
GET request for endpoint /ipam/vrfs/{id}" |
|
@leaders -min 1 -max 1 |
|
apicontextid -help\ |
|
"The name of the stored api context to use. |
|
A contextid can be created in-memory using |
|
api_context_create, or loaded from a .toml |
|
file using api_context_load."\ |
|
-choices {${[punk::netbox::api_context_names]}} |
|
@opts |
|
}\ |
|
[set ::punk::netbox::argdoc::_RETURN_DICT]\ |
|
{ |
|
@values -min 1 -max 1 |
|
id -type integer -help\ |
|
"A unique integer value identifying this VRF" |
|
}] |
|
::punk::netbox::system::make_rest_func ::punk::netbox::ipam::vrfs_read api/ipam/vrfs/{id}/ -verb get -body none |
|
|
|
|
|
punk::args::define {*}[list\ |
|
{ |
|
@dynamic |
|
@id -id ::punk::netbox::ipam::prefixes_list |
|
@cmd -name punk::netbox::ipam::prefixes_list -help\ |
|
"ipam_prefixes_list |
|
GET request for endpoint /ipam/prefixes/" |
|
@leaders -min 1 -max 1 |
|
apicontextid -help\ |
|
"The name of the stored api context to use. |
|
A contextid can be created in-memory using |
|
api_context_create, or loaded from a .toml |
|
file using api_context_load."\ |
|
-choices {${[punk::netbox::api_context_names]}} |
|
@opts |
|
-id -type integer |
|
-ID_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -help {${$::punk::netbox::argdoc::_number_filter_help}} |
|
-is_pool |
|
-mark_utilized |
|
-description -type string -help "Exact Match (case sensitive)" |
|
-DESCRIPTION_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -help {${$::punk::netbox::argdoc::_description_filter_help}} |
|
}\ |
|
[set ::punk::netbox::argdoc::_create_update_options]\ |
|
{ |
|
-q -type string -help\ |
|
"Query prefixes by substring" |
|
-tag |
|
}\ |
|
[set ::punk::netbox::argdoc::_tenant_options]\ |
|
[set ::punk::netbox::argdoc::_region_options]\ |
|
[set ::punk::netbox::argdoc::_site_options]\ |
|
[set ::punk::netbox::argdoc::_group_options]\ |
|
[set ::punk::netbox::argdoc::_role_options]\ |
|
{ |
|
-family |
|
-prefix |
|
-within |
|
-within_include |
|
-contains |
|
-depth |
|
-DEPTH_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -help {${$::punk::netbox::argdoc::_number_filter_help}} |
|
-children |
|
-CHILDREN_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -help {${$::punk::netbox::argdoc::_number_filter_help}} |
|
-mask_length |
|
-mask_length__gte |
|
-mask_length__lte |
|
-vlan_id -type integer |
|
-vlan_id__n -type integer |
|
-vlan_vid -type integer |
|
-VLAN_VID_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -help {${$::punk::netbox::argdoc::_number_filter_help}} |
|
-vrf_id |
|
-vrf |
|
-status |
|
-available_on_device |
|
-available_on_virtualmachine |
|
}\ |
|
[set ::punk::netbox::argdoc::_page_options]\ |
|
[set ::punk::netbox::argdoc::_CUSTOM_PARAMS]\ |
|
[set ::punk::netbox::argdoc::_RETURN_PAGEDICT]\ |
|
{ |
|
@values -min 0 -max 0 |
|
}] |
|
::punk::netbox::system::make_rest_func ::punk::netbox::ipam::prefixes_list api/ipam/prefixes/ -verb get -body none |
|
|
|
punk::args::define {*}[list\ |
|
{ |
|
@dynamic |
|
@id -id ::punk::netbox::ipam::prefixes_create |
|
@cmd -name punk::netbox::ipam::prefixes_create -help\ |
|
"ipam_prefixes_create |
|
POST request for endpoint /ipam/prefixes/" |
|
@leaders -min 1 -max 1 |
|
apicontextid -help\ |
|
"The name of the stored api context to use. |
|
A contextid can be created in-memory using |
|
api_context_create, or loaded from a .toml |
|
file using api_context_load."\ |
|
-choices {${[punk::netbox::api_context_names]}} |
|
@opts |
|
}\ |
|
[set ::punk::netbox::argdoc::_RETURN_DICT]\ |
|
{ |
|
@values -min 1 -max 1 |
|
body -type string -help\ |
|
"JSON string" |
|
}] |
|
::punk::netbox::system::make_rest_func ::punk::netbox::ipam::prefixes_create api/ipam/prefixes/{id}/ -verb post -body required |
|
|
|
punk::args::define {*}[list\ |
|
{ |
|
@dynamic |
|
@id -id ::punk::netbox::ipam::prefixes_read |
|
@cmd -name punk::netbox::ipam::prefixes_read -help\ |
|
"ipam_prefixes_read |
|
GET request for endpoint /ipam/prefixes/{id}/" |
|
@leaders -min 1 -max 1 |
|
apicontextid -help\ |
|
"The name of the stored api context to use. |
|
A contextid can be created in-memory using |
|
api_context_create, or loaded from a .toml |
|
file using api_context_load."\ |
|
-choices {${[punk::netbox::api_context_names]}} |
|
@opts |
|
}\ |
|
[set ::punk::netbox::argdoc::_RETURN_DICT]\ |
|
{ |
|
@values -min 1 -max 1 |
|
id -type integer -help\ |
|
"A unique integer value identifying this prefix" |
|
}] |
|
::punk::netbox::system::make_rest_func ::punk::netbox::ipam::prefixes_read api/ipam/prefixes/{id}/ -verb get -body none |
|
|
|
|
|
punk::args::define {*}[list\ |
|
{ |
|
@dynamic |
|
@id -id ::punk::netbox::ipam::prefixes_available-ips_list |
|
@cmd -name punk::netbox::ipam::prefixes_available-ips_list -help\ |
|
"ipam_prefixes_available-ips_list |
|
GET request for endpoint /ipam/prefixes/{id}/available-ips/" |
|
@leaders -min 1 -max 1 |
|
apicontextid -help\ |
|
"The name of the stored api context to use. |
|
A contextid can be created in-memory using |
|
api_context_create, or loaded from a .toml |
|
file using api_context_load."\ |
|
-choices {${[punk::netbox::api_context_names]}} |
|
@opts |
|
}\ |
|
[set ::punk::netbox::argdoc::_page_options]\ |
|
[set ::punk::netbox::argdoc::_CUSTOM_PARAMS]\ |
|
[set ::punk::netbox::argdoc::_RETURN_LISTOFDICTS]\ |
|
{ |
|
@values -min 1 -max 1 |
|
id -type integer -help\ |
|
"A unique integer value identifying this prefix" |
|
}\ |
|
] |
|
::punk::netbox::system::make_rest_func ::punk::netbox::ipam::prefixes_available-ips_list api/ipam/prefixes/{id}/available-ips/ -verb get -body none |
|
|
|
punk::args::define {*}[list\ |
|
{ |
|
@dynamic |
|
@id -id ::punk::netbox::ipam::prefixes_available-ips_create |
|
@cmd -name punk::netbox::ipam::prefixes_available-ips_create -help\ |
|
"ipam_prefixes_available-ips_create |
|
POST request for endpoint /ipam/prefixes/{id}/available-ips/" |
|
@leaders -min 1 -max 1 |
|
apicontextid -help\ |
|
"The name of the stored api context to use. |
|
A contextid can be created in-memory using |
|
api_context_create, or loaded from a .toml |
|
file using api_context_load."\ |
|
-choices {${[punk::netbox::api_context_names]}} |
|
@opts |
|
}\ |
|
[set ::punk::netbox::argdoc::_CUSTOM_PARAMS]\ |
|
[set ::punk::netbox::argdoc::_RETURN_DICT]\ |
|
{ |
|
@values -min 1 -max 2 |
|
id -type integer -help\ |
|
"A unique integer value identifying this prefix" |
|
body -type string -default "" -help\ |
|
{ |
|
If empty create a single IP with default values. |
|
(next available IP in prefix) |
|
|
|
Create 2 IPs: |
|
[ |
|
{"description": "ip1"}, |
|
{"description": "ip2"} |
|
] |
|
NOTE: This always uses next available IPs. |
|
To create a specific IP, use api/ipam/ip-addresses endpoint. |
|
|
|
The returned json is just an object if one address created, |
|
but a list if multiple. :/ |
|
|
|
} |
|
}\ |
|
] |
|
::punk::netbox::system::make_rest_func ::punk::netbox::ipam::prefixes_available-ips_create api/ipam/prefixes/{id}/available-ips/ -verb post -body required |
|
|
|
punk::args::define {*}[list\ |
|
{ |
|
@dynamic |
|
@id -id ::punk::netbox::ipam::ip-addresses_list |
|
@cmd -name punk::netbox::ipam::ip-addresses_list -help\ |
|
"ipam_ip-addresses_list |
|
GET request for endpoint /ipam/ip-addresses/" |
|
@leaders -min 1 -max 1 |
|
apicontextid -help\ |
|
"The name of the stored api context to use. |
|
A contextid can be created in-memory using |
|
api_context_create, or loaded from a .toml |
|
file using api_context_load."\ |
|
-choices {${[punk::netbox::api_context_names]}} |
|
@opts |
|
-id -type integer |
|
-ID_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -help {${$::punk::netbox::argdoc::_number_filter_help}} |
|
-dns_name |
|
-DNS_NAME_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -help {${$::punk::netbox::argdoc::_string_filter_help}} |
|
-description -type string -help "Exact Match (case sensitive)" |
|
-DESCRIPTION_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -help {${$::punk::netbox::argdoc::_description_filter_help}} |
|
}\ |
|
[set ::punk::netbox::argdoc::_create_update_options]\ |
|
{ |
|
-q |
|
-tag |
|
}\ |
|
[set ::punk::netbox::argdoc::_tenant_options]\ |
|
[set ::punk::netbox::argdoc::_region_options]\ |
|
[set ::punk::netbox::argdoc::_site_options]\ |
|
[set ::punk::netbox::argdoc::_group_options]\ |
|
[set ::punk::netbox::argdoc::_role_options]\ |
|
{ |
|
-family |
|
-parent |
|
-address |
|
-mask_length |
|
-vrf_id |
|
-vrf |
|
-present_in_vrf_id |
|
-present_in_vrf |
|
-device |
|
-device_id |
|
-virtual_machine |
|
-virtual_machine_id |
|
-interface |
|
-interface_id |
|
-vminterface |
|
-vminterface_id |
|
-fhrpgroup_id |
|
-assigned_to_interface |
|
-status |
|
-role |
|
-available_on_device |
|
-available_on_virtualmachine |
|
}\ |
|
[set ::punk::netbox::argdoc::_page_options]\ |
|
[set ::punk::netbox::argdoc::_CUSTOM_PARAMS]\ |
|
[set ::punk::netbox::argdoc::_RETURN_PAGEDICT]\ |
|
{ |
|
@values -min 0 -max 0 |
|
}] |
|
::punk::netbox::system::make_rest_func ::punk::netbox::ipam::ip-addresses_list api/ipam/ip-addresses/ -verb get -body none |
|
|
|
punk::args::define {*}[list\ |
|
{ |
|
@dynamic |
|
@id -id ::punk::netbox::ipam::ip-addresses_read |
|
@cmd -name punk::netbox::ipam::ip-addresses_read -help\ |
|
"ipam_ip-addresses_read |
|
GET request for endpoint /ipam/ip-addresses/{id}/" |
|
@leaders -min 1 -max 1 |
|
apicontextid -help\ |
|
"The name of the stored api context to use. |
|
A contextid can be created in-memory using |
|
api_context_create, or loaded from a .toml |
|
file using api_context_load."\ |
|
-choices {${[punk::netbox::api_context_names]}} |
|
@opts |
|
}\ |
|
[set ::punk::netbox::argdoc::_RETURN_DICT]\ |
|
{ |
|
@values -min 1 -max 1 |
|
id -type integer |
|
}] |
|
::punk::netbox::system::make_rest_func ::punk::netbox::ipam::ip-addresses_read api/ipam/ip-addresses/{id}/ -verb get -body none |
|
|
|
punk::args::define {*}[list\ |
|
{ |
|
@dynamic |
|
@id -id ::punk::netbox::ipam::ip-addresses_create |
|
@cmd -name punk::netbox::ipam::ip-addresses_create -help\ |
|
"ipam_ip-addresses_create |
|
POST request for endpoint /ipam/ip-addresses/" |
|
@leaders -min 1 -max 1 |
|
apicontextid -help\ |
|
"The name of the stored api context to use. |
|
A contextid can be created in-memory using |
|
api_context_create, or loaded from a .toml |
|
file using api_context_load."\ |
|
-choices {${[punk::netbox::api_context_names]}} |
|
@opts |
|
}\ |
|
[set ::punk::netbox::argdoc::_RETURN_DICT]\ |
|
{ |
|
@values -min 1 -max 1 |
|
body -type string -help\ |
|
{JSON string |
|
Example: |
|
{ |
|
"address": "string", |
|
"vrf": 0, |
|
"tenant": 0, |
|
"status": "active", |
|
"role": "loopback", |
|
"assigned_object_type": "string", |
|
"assigned_object_id": 0, |
|
"nat_inside": 0, |
|
"dns_name": "string", |
|
"description": "string", |
|
"tags": [ |
|
{ |
|
"name": "string", |
|
"slug": "string", |
|
"color": "string" |
|
} |
|
], |
|
"custom_fields": {} |
|
} |
|
Required: address (IPv4 or IPV6 address with mask) |
|
} |
|
}] |
|
::punk::netbox::system::make_rest_func ::punk::netbox::ipam::ip-addresses_create api/ipam/ip-addresses/ -verb post -body required |
|
|
|
punk::args::define {*}[list\ |
|
{ |
|
@dynamic |
|
@id -id ::punk::netbox::ipam::ip-addresses_bulk_partial_update |
|
@cmd -name punk::netbox::ipam::ip-addresses_bulk_partial_update -help\ |
|
"ipam_ip-addresses_bulk_partical_update |
|
PATCH request for endpoint /ipam/ip-addresses/" |
|
@leaders -min 1 -max 1 |
|
apicontextid -help\ |
|
"The name of the stored api context to use. |
|
A contextid can be created in-memory using |
|
api_context_create, or loaded from a .toml |
|
file using api_context_load."\ |
|
-choices {${[punk::netbox::api_context_names]}} |
|
@opts |
|
}\ |
|
[set ::punk::netbox::argdoc::_RETURN_DICT]\ |
|
{ |
|
@values -min 1 -max 1 |
|
body -type string -help\ |
|
{JSON string |
|
model: |
|
{ |
|
"address": "string", |
|
"vrf": 0, |
|
"tenant": 0, |
|
"status": "active", |
|
"role": "loopback", |
|
"assigned_object_type": "string", |
|
"assigned_object_id": 0, |
|
"nat_inside": 0, |
|
"dns_name": "string", |
|
"description": "string", |
|
"tags": [ |
|
{ |
|
"name": "string", |
|
"slug": "string", |
|
"color": "string" |
|
} |
|
], |
|
"custom_fields": {} |
|
} |
|
required: address |
|
} |
|
}] |
|
::punk::netbox::system::make_rest_func ::punk::netbox::ipam::ip-addresses_bulk_partial_update api/ipam/ip-addresses/ -verb patch -body required |
|
|
|
} |
|
tcl::namespace::eval punk::netbox::tenancy { |
|
namespace export {[a-z]*} |
|
lappend PUNKARGS [list\ |
|
{ |
|
@dynamic |
|
@id -id ::punk::netbox::tenancy::tenants_list |
|
@cmd -name punk::netbox::tenancy::tenants_list -help\ |
|
"tenancy_tenants_list |
|
GET request for endpoint /tenancy/tenants/" |
|
@leaders -min 1 -max 1 |
|
apicontextid -help\ |
|
"The name of the stored api context to use. |
|
A contextid can be created in-memory using |
|
api_context_create, or loaded from a .toml |
|
file using api_context_load."\ |
|
-choices {${[punk::netbox::api_context_names]}} |
|
@opts |
|
-id -type integer |
|
-ID_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -help {${$::punk::netbox::argdoc::_number_filter_help}} |
|
-name |
|
-NAME_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -help {${$::punk::netbox::argdoc::_name_filter_help}} |
|
-slug -type string |
|
-SLUG_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -help {${$::punk::netbox::argdoc::_string_filter_help}} |
|
-description -type string |
|
-DESCRIPTION_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -help {${$::punk::netbox::argdoc::_string_filter_help}} |
|
}\ |
|
[set ::punk::netbox::argdoc::_create_update_options]\ |
|
{ |
|
-q -type string |
|
-tag -type string |
|
-tag__n -type string |
|
}\ |
|
[set ::punk::netbox::argdoc::_tenant_options]\ |
|
[set ::punk::netbox::argdoc::_contact_options]\ |
|
{ |
|
}\ |
|
{ |
|
}\ |
|
[set ::punk::netbox::argdoc::_group_options]\ |
|
{ |
|
}\ |
|
[set ::punk::netbox::argdoc::_page_options]\ |
|
[set ::punk::netbox::argdoc::_CUSTOM_PARAMS]\ |
|
[set ::punk::netbox::argdoc::_RETURN_PAGEDICT]\ |
|
{ |
|
@values -min 0 -max 0 |
|
}] |
|
::punk::netbox::system::make_rest_func ::punk::netbox::tenancy::tenants_list api/tenancy/tenants/ -verb get -body none |
|
} |
|
|
|
tcl::namespace::eval punk::netbox::virtualization { |
|
namespace export {[a-z]*} |
|
lappend PUNKARGS [list\ |
|
{ |
|
@dynamic |
|
@id -id ::punk::netbox::virtualization::virtual-machines_list |
|
@cmd -name punk::netbox::virtualization::virtual-machines_list -help\ |
|
"virtualization_virtual-machines_list |
|
GET request for endpoint /virtualization/virtual-machines/" |
|
@leaders -min 1 -max 1 |
|
apicontextid -help\ |
|
"The name of the stored api context to use. |
|
A contextid can be created in-memory using |
|
api_context_create, or loaded from a .toml |
|
file using api_context_load."\ |
|
-choices {${[punk::netbox::api_context_names]}} |
|
@opts |
|
-id -type integer |
|
-ID_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -help {${$::punk::netbox::argdoc::_number_filter_help}} |
|
-name |
|
-NAME_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -help {${$::punk::netbox::argdoc::_name_filter_help}} |
|
-cluster -type string |
|
-cluster_n -type string |
|
-vcpus -type integer |
|
-VCPUS_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -help {${$::punk::netbox::argdoc::_number_filter_help}} |
|
-memory -type integer -help\ |
|
"Whole number" |
|
-MEMORY_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -help {${$::punk::netbox::argdoc::_number_filter_help}} |
|
-disk -type integer |
|
-DISK_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -help {${$::punk::netbox::argdoc::_number_filter_help}} |
|
}\ |
|
[set ::punk::netbox::argdoc::_create_update_options]\ |
|
{ |
|
-q |
|
-tag |
|
}\ |
|
[set ::punk::netbox::argdoc::_tenant_options]\ |
|
[set ::punk::netbox::argdoc::_contact_options]\ |
|
{ |
|
-local_context_data |
|
-status |
|
-status_n |
|
-cluster_group_id |
|
-cluster_group_id__n |
|
-cluster_group |
|
-cluster_group__n |
|
-cluster_type_id |
|
-cluster_type_id__n |
|
-cluster_type |
|
-cluster_type__n |
|
-cluster_id |
|
-cluster_id__n |
|
}\ |
|
[set ::punk::netbox::argdoc::_region_options]\ |
|
[set ::punk::netbox::argdoc::_site_options]\ |
|
{ |
|
-platform |
|
-platform__n |
|
-mac_address |
|
-MAC_ADDRESS_FILTER -type list -minsize 2 -maxsize 2 -multiple 1 -help {${$::punk::netbox::argdoc::_string_filter_help}} |
|
-has_primary_ip |
|
}\ |
|
[set ::punk::netbox::argdoc::_group_options]\ |
|
[set ::punk::netbox::argdoc::_role_options]\ |
|
{ |
|
}\ |
|
[set ::punk::netbox::argdoc::_page_options]\ |
|
[set ::punk::netbox::argdoc::_CUSTOM_PARAMS]\ |
|
[set ::punk::netbox::argdoc::_RETURN_PAGEDICT]\ |
|
{ |
|
@values -min 0 -max 0 |
|
}] |
|
::punk::netbox::system::make_rest_func ::punk::netbox::virtualization::virtual-machines_list api/virtualization/virtual-machines/ -verb get -body none |
|
|
|
lappend PUNKARGS [list\ |
|
{ |
|
@dynamic |
|
@id -id ::punk::netbox::virtualization::virtual-machines_create |
|
@cmd -name punk::netbox::virtualization::virtual-machines_create -help\ |
|
"virtualization_virtual-machines_create |
|
GET request for endpoint /virtualization/virtual-machines/" |
|
@leaders -min 1 -max 1 |
|
apicontextid -help\ |
|
"The name of the stored api context to use. |
|
A contextid can be created in-memory using |
|
api_context_create, or loaded from a .toml |
|
file using api_context_load."\ |
|
-choices {${[punk::netbox::api_context_names]}} |
|
@opts |
|
}\ |
|
[set ::punk::netbox::argdoc::_RETURN_DICT]\ |
|
{ |
|
@values -min 2 -max 2 |
|
id -type integer -help\ |
|
"A unique integer value identifying this virtual machine" |
|
body -type string -help\ |
|
"JSON string" |
|
}] |
|
::punk::netbox::system::make_rest_func ::punk::netbox::virtualization::virtual-machines_create api/virtualization/virtual-machines/ -verb post -body required |
|
|
|
lappend PUNKARGS [list\ |
|
{ |
|
@dynamic |
|
@id -id ::punk::netbox::virtualization::virtual-machines_delete |
|
@cmd -name punk::netbox::virtualization::virtual-machines_delete -help\ |
|
"virtualization_virtual-machines_delete |
|
DELETE request for endpoint /virtualization/virtual-machines/ |
|
HTTP code: 204 |
|
" |
|
@leaders -min 1 -max 1 |
|
apicontextid -help\ |
|
"The name of the stored api context to use. |
|
A contextid can be created in-memory using |
|
api_context_create, or loaded from a .toml |
|
file using api_context_load."\ |
|
-choices {${[punk::netbox::api_context_names]}} |
|
@opts |
|
-FORCE -default 0 -type boolean -help\ |
|
"Set to true to BULK delete all items at this endpoint" |
|
}\ |
|
{ |
|
@values -min 0 -max 0 |
|
}] |
|
::punk::netbox::system::make_rest_func ::punk::netbox::virtualization::virtual-machines_delete api/virtualization/virtual-machines/ -verb delete -body none |
|
|
|
|
|
lappend PUNKARGS [list\ |
|
{ |
|
@dynamic |
|
@id -id ::punk::netbox::virtualization::virtual-machines_read |
|
@cmd -name punk::netbox::virtualization::virtual-machines_read -help\ |
|
"virtualization_virtual-machines_read |
|
GET request for endpoint /virtualization/virtual-machines/{id}" |
|
@leaders -min 1 -max 1 |
|
apicontextid -help\ |
|
"The name of the stored api context to use. |
|
A contextid can be created in-memory using |
|
api_context_create, or loaded from a .toml |
|
file using api_context_load."\ |
|
-choices {${[punk::netbox::api_context_names]}} |
|
@opts |
|
}\ |
|
[set ::punk::netbox::argdoc::_RETURN_DICT]\ |
|
{ |
|
@values -min 1 -max 1 |
|
id -type integer -help\ |
|
"A unique integer value identifying this virtual machine" |
|
}] |
|
::punk::netbox::system::make_rest_func ::punk::netbox::virtualization::virtual-machines_read api/virtualization/virtual-machines/{id}/ -verb get -body none |
|
|
|
lappend PUNKARGS [list\ |
|
{ |
|
@dynamic |
|
@id -id ::punk::netbox::virtualization::virtual-machines_update |
|
@cmd -name punk::netbox::virtualization::virtual-machines_update -help\ |
|
"virtualization_virtual-machines_update |
|
PUT request for endpoint /virtualization/virtual-machines/{id}" |
|
@leaders -min 1 -max 1 |
|
apicontextid -help\ |
|
"The name of the stored api context to use. |
|
A contextid can be created in-memory using |
|
api_context_create, or loaded from a .toml |
|
file using api_context_load."\ |
|
-choices {${[punk::netbox::api_context_names]}} |
|
@opts |
|
}\ |
|
[set ::punk::netbox::argdoc::_RETURN_DICT]\ |
|
{ |
|
@values -min 2 -max 2 |
|
id -type integer -help\ |
|
"A unique integer value identifying this virtual machine" |
|
body -type string -help\ |
|
"JSON string" |
|
}] |
|
::punk::netbox::system::make_rest_func ::punk::netbox::virtualization::virtual-machines_update api/virtualization/virtual-machines/{id}/ -verb put -body required |
|
} |
|
|
|
|
|
|
|
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
|
# Secondary API namespace |
|
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
|
tcl::namespace::eval punk::netbox::lib { |
|
tcl::namespace::export {[a-z]*} ;# Convention: export all lowercase |
|
tcl::namespace::path [tcl::namespace::parent] |
|
#*** !doctools |
|
#[subsection {Namespace punk::netbox::lib}] |
|
#[para] Secondary functions that are part of the API |
|
#[list_begin definitions] |
|
|
|
#proc utility1 {p1 args} { |
|
# #*** !doctools |
|
# #[call lib::[fun utility1] [arg p1] [opt {?option value...?}]] |
|
# #[para]Description of utility1 |
|
# return 1 |
|
#} |
|
|
|
|
|
|
|
#*** !doctools |
|
#[list_end] [comment {--- end definitions namespace punk::netbox::lib ---}] |
|
} |
|
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
|
|
|
|
|
|
|
|
|
|
|
# == === === === === === === === === === === === === === === |
|
# Sample 'about' function with punk::args documentation |
|
# == === === === === === === === === === === === === === === |
|
tcl::namespace::eval punk::netbox { |
|
tcl::namespace::export {[a-z]*} ;# Convention: export all lowercase |
|
variable PUNKARGS |
|
variable PUNKARGS_aliases |
|
|
|
lappend PUNKARGS [list { |
|
@id -id "(package)punk::netbox" |
|
@package -name "punk::netbox" -help\ |
|
"Package |
|
Description" |
|
}] |
|
|
|
namespace eval argdoc { |
|
#namespace for custom argument documentation |
|
proc package_name {} { |
|
return punk::netbox |
|
} |
|
proc about_topics {} { |
|
#info commands results are returned in an arbitrary order (like array keys) |
|
set topic_funs [info commands [namespace current]::get_topic_*] |
|
set about_topics [list] |
|
foreach f $topic_funs { |
|
set tail [namespace tail $f] |
|
lappend about_topics [string range $tail [string length get_topic_] end] |
|
} |
|
#Adjust this function or 'default_topics' if a different order is required |
|
return [lsort $about_topics] |
|
} |
|
proc default_topics {} {return [list Description *]} |
|
|
|
# ------------------------------------------------------------- |
|
# get_topic_ functions add more to auto-include in about topicg |
|
# ------------------------------------------------------------- |
|
proc get_topic_Description {} { |
|
punk::args::lib::tstr [string trim { |
|
package punk::netbox |
|
A library for calling netbox REST functions |
|
} \n] |
|
} |
|
proc get_topic_License {} { |
|
return "MIT" |
|
} |
|
proc get_topic_Version {} { |
|
return "$::punk::netbox::version" |
|
} |
|
proc get_topic_Contributors {} { |
|
set authors {{Julian Noble <julian@precisium.com.au>}} |
|
set contributors "" |
|
foreach a $authors { |
|
append contributors $a \n |
|
} |
|
if {[string index $contributors end] eq "\n"} { |
|
set contributors [string range $contributors 0 end-1] |
|
} |
|
return $contributors |
|
} |
|
proc get_topic_features {} { |
|
punk::args::lib::tstr -return string { |
|
netbox /status/ endpoint |
|
beginnings of /ipam/ endpoints |
|
beginnings of /virtualization/ endpoints |
|
} |
|
} |
|
# ------------------------------------------------------------- |
|
} |
|
|
|
# we re-use the argument definition from punk::args::standard_about and override some items |
|
set overrides [dict create] |
|
dict set overrides @id -id "::punk::netbox::about" |
|
dict set overrides @cmd -name "punk::netbox::about" |
|
dict set overrides @cmd -help [string trim [punk::args::lib::tstr { |
|
About punk::netbox |
|
}] \n] |
|
dict set overrides topic -choices [list {*}[punk::netbox::argdoc::about_topics] *] |
|
dict set overrides topic -choicerestricted 1 |
|
dict set overrides topic -default [punk::netbox::argdoc::default_topics] ;#if -default is present 'topic' will always appear in parsed 'values' dict |
|
set newdef [punk::args::resolved_def -antiglobs -package_about_namespace -override $overrides ::punk::args::package::standard_about *] |
|
lappend PUNKARGS [list $newdef] |
|
proc about {args} { |
|
package require punk::args |
|
#standard_about accepts additional choices for topic - but we need to normalize any abbreviations to full topic name before passing on |
|
set argd [punk::args::parse $args withid ::punk::netbox::about] |
|
lassign [dict values $argd] _leaders opts values _received |
|
punk::args::package::standard_about -package_about_namespace ::punk::netbox::argdoc {*}$opts {*}[dict get $values topic] |
|
} |
|
} |
|
# end of sample 'about' function |
|
# == === === === === === === === === === === === === === === |
|
|
|
|
|
# ----------------------------------------------------------------------------- |
|
# register namespace(s) to have PUNKARGS,PUNKARGS_aliases variables checked |
|
# ----------------------------------------------------------------------------- |
|
# variable PUNKARGS |
|
# variable PUNKARGS_aliases |
|
namespace eval ::punk::args::register { |
|
#use fully qualified so 8.6 doesn't find existing var in global namespace |
|
lappend ::punk::args::register::NAMESPACES\ |
|
::punk::netbox\ |
|
::punk::netbox::dcim\ |
|
::punk::netbox::ipam\ |
|
::punk::netbox::tenancy\ |
|
::punk::netbox::virtualization |
|
} |
|
# ----------------------------------------------------------------------------- |
|
|
|
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
|
## Ready |
|
package provide punk::netbox [tcl::namespace::eval punk::netbox { |
|
variable pkg punk::netbox |
|
variable version |
|
set version 999999.0a1.0 |
|
}] |
|
return |
|
|
|
#*** !doctools |
|
#[manpage_end] |
|
|
|
|