Closed patrickfnielsen closed 9 months ago
can you share some output of what things look like in a terminal if you were configuring/showing stuff in both scenarios?
you could have a configuration level configuration
and another configuration-vdom
maybe, we have some stuff like that for configure vs configure exclusive (XR/junos). im not sure I fully follow the part where you need interim prompt and having to re-escalate though so maybe the example will help me grok it.
in general though, the SendConfig{s}
stuff is really just convenience around SendCommand{s}
anyway, so if it doesnt fit right/well then I think it seems very reasonable to just use the send commands. again, maybe some terminal output will give me a better idea though, so we'll see!
also just for context -- vdom is something like a firewall context or something? doesnt matter of course, just curious :p
Sure thing - Here's a few examples. When VDOM's are in use, the following syntax would be use:
fw-2 # config vdom
fw-2 (vdom) # edit fw-inet
current vf=fw-inet:1
fw-2 (fw-inet) # get system interface
== [ ha ]
name: ha mode: static ip: 0.0.0.0 0.0.0.0 status: up netbios-forward: disable type: physical netflow-sampler: disable sflow-sampler: disable src-check: enable explicit-web-proxy: disable explicit-ftp-proxy: disable proxy-captive-portal: disable trunk: disable mtu-override: disable wccp: disable drop-overlapped-fragment: disable drop-fragment: disable
== [ mgmt ]
name: mgmt ip: 10.1.1.1 255.255.255.192 status: up netbios-forward: disable type: physical netflow-sampler: disable sflow-sampler: disable src-check: enable explicit-web-proxy: disable explicit-ftp-proxy: disable proxy-captive-portal: disable trunk: disable mtu-override: disable wccp: disable drop-overlapped-fragment: disable drop-fragment: disable
fw-2 (fw-inet) # end
fw-2 #
fw-2 (fw-inet) # config system interface
fw-2 (interface) #
If VDOM's are not used, it would be the following:
fw-2 # get system interface
== [ ha ]
name: ha mode: static ip: 0.0.0.0 0.0.0.0 status: up netbios-forward: disable type: physical netflow-sampler: disable sflow-sampler: disable src-check: enable explicit-web-proxy: disable explicit-ftp-proxy: disable proxy-captive-portal: disable trunk: disable mtu-override: disable wccp: disable drop-overlapped-fragment: disable drop-fragment: disable
== [ mgmt ]
name: mgmt ip: 10.1.1.1 255.255.255.192 status: up netbios-forward: disable type: physical netflow-sampler: disable sflow-sampler: disable src-check: enable explicit-web-proxy: disable explicit-ftp-proxy: disable proxy-captive-portal: disable trunk: disable mtu-override: disable wccp: disable drop-overlapped-fragment: disable drop-fragment: disable
With regards to configuration:
When in VDOM mode I guess the config vdom
would be equal to conf t
on a cisco device, and I would have to add an edit <vdom-name>
to all my config - that is workable, and it would be possible to escalate and deescalate from.
When not in VDOM mode there is no single config command:
fw-2 # config
alertemail Alert email configuration.
antivirus AntiVirus configuration.
application Application control configuration.
authentication authentication
dlp DLP configuration.
dnsfilter DNS filter configuration.
emailfilter AntiSpam configuration.
endpoint-control Endpoint control configuration.
extender-controller FortiExtender controller configuration.
file-filter file-filter
firewall Firewall configuration.
ftp-proxy FTP proxy configuration.
icap ICAP client configuration.
ips IPS configuration.
log Log configuration.
router Router configuration.
sctp-filter SCTP filter configuration.
ssh-filter SSH filter configuration.
switch-controller External FortiSwitch configuration.
system System operation configuration.
user Authentication configuration.
videofilter videofilter
voip VoIP configuration.
vpn VPN configuration.
waf Web Application Firewall configuration.
web-proxy Web proxy configuration.
webfilter Web filter configuration.
wireless-controller Wireless access point configuration.
fw-2 # config system interface
fw-2 (interface) #
So I would either have to create a config context for all those + one for VDOM, or just not use the SendConfig
command, and make the the prompt in SendCommand
generic to support all possible prompts.
With regards to the interim prompt - It's not needed if I just create a prompt pattern that supports all scenarios like the following: [\w_-]+ (?:\([\w_-]+\)? )?[$#]
. But by doing this I miss out on the SendConfig
command and automatic deesclation, though not an major issue I was just wondering if there was any better way?
Maybe by having the library check for all prompts and detected that the privilege level has been escalated to configuration automatically, but since it knows what level it should be in it could send the deescalate command - Though this might be a lot of work for little gain.
And yes VDOM's are to some extent like contexts, basically "virtual" firewalls with it's own config :)
@patrickfnielsen awesome, thanks for the great detail!
I wonder if this may be a solid opportunity for a not well (or at all???) documented feature/thing "variants".
tl;dr here is that the idea is you have some platform, lets say "acme_os", and that there is some scenario where there are some slight differences, for example (and similar here!) acme-os behaves a bit differently in a multi supervisor type setup. with a variant you can expand the base "acme-os" to add additional privilege levels or to change the "Failed when contains" list or something like that.
so im wondering if the base platform could be "fortigate-fortios" then a variant for "vdom" ; in this case the base platform would not have a configuration level and you would just use send command(s), and the variant would have a configuration level that gets you into "config vdom" mode? but maybe this isn't still very nice since you'd kinda need the name of the vdom?
because we are talking scrapligo and not python we are a little more constrained with how much we can just kinda yolo some stuff :) in python you could write a community platform and that gets you the ability to override methods to basically make this behave way more like you want -- check out the fortigate python platform if you haven't already, Viktor did some cool stuff over there. perhaps an alternative option that gets you the ability to do sorta what Viktor has done is to have a scrapli-fortigate
package that accepts a network driver as an argument and then does XYZ, so you could just have a generic driver and then wrap that with your package. maybe it could look like:
type FortiWrapper struct {
*network.Driver
}
func (w *FortiWrapper) DoStuff() {
w.SendCommand("foo")
}
func main() {
p, err := platform.NewPlatform(
"fortigate_fortios",
"1.2.3.4",
)
if err != nil {
panic(err)
}
d, err := p.GetNetworkDriver()
if err != nil {
panic(err)
}
// maybe second arg here is "true/false" for vdom, or you could do options or whatever of course
// this thing could embed
fw := FortiWrapper{d}
fw.SendConfigs("blah")
fw.DoStuff()
}
This raises a bigger point that ive long wanted to address but just never have had enough of a need: how can we enable scrapli_community like extensions (like Viktor's linked above that adds some methods and overrides some others) in scrapligo. I'm sure there is an answer/way but I surely do not know what it is :D if you have thoughts I am all ears!
Last bits for now:
With regards to the interim prompt - It's not needed if I just create a prompt pattern that supports all scenarios like the following: [\w-]+ (?:([\w-]+)? )?[$#]. But by doing this I miss out on the SendConfig command and automatic deesclation, though not a major issue I was just wondering if there was any better way?
I would defo not add all the patterns to the prompt -- you can and it would/could work, but it will be hellaciously slow. this is the slowest part of scrapligo and I was actually tinkering this past weekend too see if there are any easy ways to make the prompt matching a bit more efficient. maybe more to come on that.
Maybe by having the library check for all prompts and detected that the privilege level has been escalated to configuration automatically, but since it knows what level it should be in it could send the deescalate command - Though this might be a lot of work for little gain.
So... this partly falls in line w/ the above comment too -- historically (for better or maybe worse??) we've only ever actually checked/asserted that we are at the correct priv level when a user calls AcquirePriv
or calls that in a round about way by calling SendConfig(s)
. As things stand the "base" prompt pattern actually is always a compiled pattern of all privilege levels (part of why this is hellaciously slow/inefficient!) so we don't actually ever "fail" to find a prompt even if a user escalates/deescalates on their own outside of the "normal" flow of things. So I think doing what you propose actually is fairly trivial (just an acquirePriv call in send command to acquire the default desired privilege similar to what we do in send configs), but... im not sure I love it? Im not sure I have good reasons/thoughts about why at the moment though other than its for sure extra overhead in terms of time/commands to send/parse/etc.. I'll think on this one though and maybe come back with smarter words :p
Ok, sorry for the wall of text. im not actually sure that helped move things along but I think I should quit while im already behind... so let us know what ya think/if that helps at all!
Thanks for the great feedback, it does help and I appreciate it!
I would prefer one platform, as I simply think it's cleaner - and because I dont always know if VDOM's are enabled or not before i connect.
I like the idea of the FortiWrapper
- and for now - I think that is what I'm going to go with, as it will allow me to hide some of the VDOM handling away, and also overwrite SendConfigs
to use SendCommands
.
With regards to scrapli_community like extensions, I could definitely see the use case as well, I'm not 100% sure how we could do it in the best way though - I'll try and think a bit about it and get back to you!
One thing I did consider was to extend the network-on-open commands to be able to capture output, and store that for use by the driver later, though this could also be done by using the FortiWrapper
you mentioned.
nice! sounds like a path forward for now at least. ill go ahead and close this but feel free to reopen or hit us up on discord if you wanna pow wow more (network automation hangout or containerlab or srlinux servers)!
I've been working on getting scrapligo work properly on a FortiGate, and I've run into a few issues. I've created the following bare bones platform:
I have a few issues though, and maybe there's already a solution I just haven't found.
Configuration - and show commands - on fortigates depends on whether or not vdom's are enabled. If a VDOM is enabled most commands have to follow the below syntax:
Without VDOM it's just:
I can handle that my self - but the fortigate also changes the prompt when doing so - so it starts as "fw-1 #" and ends as "fw-1 (vdom_name) #". I have found
opoptions.WithInterimPromptPattern
and that does work, but I have to add an explicit "end" to my config snippet above since priv is not automatically reset.I see no way to get
SendConfigs
to work as escalate again depends on if vdoms are enabled, or not - Is there any way to get this to work, or should i just "skip" usingSendConfigs
and do it usingSendCommands
?