Skip to content

Commit

Permalink
xml list control
Browse files Browse the repository at this point in the history
  • Loading branch information
mihakralj committed Sep 23, 2023
1 parent 7230fdc commit cadbd2d
Show file tree
Hide file tree
Showing 18 changed files with 168 additions and 90 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,6 @@ jobs:
echo -e "name: opnsense-cli\nversion: ${VERSION}\norigin: net-mgmt/opnsense-cli\ncomment: \"CLI to manage and monitor OPNsense firewall configuration, check status, change settings, and execute commands.\"\ndesc: \"opnsense is a command-line utility for managing, configuring, and monitoring OPNsense firewall systems. It facilitates non-GUI administration, both directly in the shell and remotely via an SSH tunnel. All interactions with OPNsense utilize the same mechanisms as the Web GUI, including staged modifications of config.xml and execution of available configd commands.\"\nmaintainer: \"[email protected]\"\nwww: \"https://github.com/mihakralj/opnsense-cli\"\nabi: \"FreeBSD:*:amd64\"\nprefix: /usr/local\nflatsize: ${flatsize}" > /Users/runner/work/opnsense-cli/opnsense-cli/manifest
echo -e "files: {\n \"/usr/local/bin/opnsense\": \"${checksum}\",\n}" >> /Users/runner/work/opnsense-cli/opnsense-cli/manifest
pkg create -M /Users/runner/work/opnsense-cli/opnsense-cli/manifest -o /Users/runner/work/opnsense-cli/opnsense-cli/ -f txz
mv opnsense-cli-*.pkg *.txz
ls -l
- name: Upload all artifacts
Expand All @@ -175,6 +174,7 @@ jobs:
./opnsense-macos
./opnsense*.txz
./opnsense.pkg
./opnsense-cli-*.pkg
release:
needs: [linuxwindows, macbsd]
Expand Down
50 changes: 9 additions & 41 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ Administrators typically only two options how to manage the firewall: either th

### Commands

- **`show system [<xpath>]`**: Retrieves system information from the firewall.
- **`show config [<xpath>]`**: Displays xpath segment of config.xml.
- **`show backup [<backup.xml>]`**: Lists available backup configs or displays a specific backup.
- **`sysctl [<xpath>]`**: Retrieves system information from the firewall.
- **`show [<xpath>]`**: Displays xpath segment of config.xml.
- **`backups [<backup.xml>]`**: Lists available backup configs or displays a specific backup.
- **`run <service> <command>`**: Executes commands on OPNsense.
- **`set <xpath> value <value>`**: Sets a value of a specific node in staging.xml file.
- **`commit`**: Moves staging.xml to active config.xml.
Expand All @@ -36,49 +36,17 @@ Administrators typically only two options how to manage the firewall: either th
- **`delete age [days]`**: Deletes all backups older than specified days
- **`delete keep [count]`**: Keeps specified number of backups and deletes the rest
- **`delete trim [count]`**: Deletes number of the oldest backups
- **`set <xpath> [value] [(attribute)]`**: Adds a new branch, value and/or attribute
- **`set <xpath> [value] [(attribute)] -d`**: Deletes branch, value and/or attribute

### Flags

- **`--target (-t)`**: Sets the target OPNsense in the form of `user@hostname[:port]`.
- **`--no-color (-n)`**: Disable ANSI color output
- **`--force (-f)`**: Removes checks and prompts before `config.xml` or `configctl` are touched.
- **`--depth (-d)`**: Specifies the number of branch levels to show.
- **`--verbose (-v)`**: Sets verbosity (1=error, 2=warning, 3=info, 4=note, 5=debug).
- **`--no-color (-n)`**: Removes ANSI colors from the printout.
- **`--xml`**: Displays results in XML format.
- **`--json`**: Displays results in JSON format.
- **`--yaml`**: Displays results in YAML format.
- **`--xml (-x)`**: Displays results in XML format.
- **`--json (-j)`**: Displays results in JSON format.
- **`--yaml (-y)`**: Displays results in YAML format.

## Installation

### FreeBSD 12/13

installs to `usr/local/bin`:
```bash
sudo pkg add https://github.com/mihakralj/opnsense-cli/releases/download/beta/opnsense.txz
```
### Debian/Ubuntu

installs to `usr/local/bin`:
```bash
curl -O https://github.com/mihakralj/opnsense-cli/releases/download/beta/opnsense.deb
dpkg -i opnsense.deb
```

### macOS
Package install (installs to `/usr/local/bin`):
```bash
curl -O https://github.com/mihakralj/opnsense-cli/releases/download/beta/opnsense.pkg
sudo installer -pkg opnsense.pkg -target /
```

signed binary:
```bash
curl -O https://github.com/mihakralj/opnsense-cli/releases/download/beta/opnsense -O opnsense
sudo chmod +x opnsense
```

### Windows
executable `opnsense.exe`:
```powershell
Invoke-WebRequest -Uri https://github.com/mihakralj/opnsense-cli/releases/download/beta/opnsense.exe -OutFile opnsense.exe
```
19 changes: 5 additions & 14 deletions cmd/backups.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,18 @@ import (
var backupsCmd = &cobra.Command{
Use: "backups",
Short: `List available backup configurations in '/conf/backup' directory`,
Long: `The 'backups' command provides functionalities for managing and viewing backup XML configurations within your OPNsense firewall system. You can list all backup configurations or get details about a specific one.`,
Example:` show backup Lists all backup XML configurations.
Long: `The 'backups' command provides functionalities for managing and viewing backup XML configurations within your OPNsense firewall system. You can list all backup configurations or get details about a specific one.`,
Example: ` show backup Lists all backup XML configurations.
show backup <config> Show details of a specific backup XML configuration`,
Run: func(cmd *cobra.Command, args []string) {

backupdir := "/conf/backup/"
path := "backups"
internal.Checkos()
backupdoc := etree.NewDocument()
bash := fmt.Sprintf(`count=$(find %s -type f | wc -l | sed -e 's/^[[:space:]]*//') && echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<backups count=\"$count\">" &&
find /conf/backup -type f -exec sh -c 'echo $(stat -f "%%m" "$1") $(basename "$1") $(stat -f "%%z" "$1") $(md5sum "$1")' sh {} \; | sort -nr -k1 |
awk '{
date = strftime("%%Y-%%m-%%dT%%H:%%M:%%S", $1)
delta = systime() - $1;
days = int(delta / 86400);
hours = int((delta %% 86400) / 3600);
minutes = int((delta %% 3600) / 60);
seconds = int(delta %% 60);
age = days "d " hours "h " minutes "m " seconds "s";
print " <" $2 " age=\"" age "\"><date>" date "</date><size>" $3 "</size><md5>" $4 "</md5></" $2 ">";}
END { print "</backups>"; }'`, backupdir)
bash := fmt.Sprintf(`echo -n "<?xml version=##1.0## encoding=##UTF-8##?>\n<backups count=##" | sed 's/##/"/g' && find %s -type f | wc -l | sed -e 's/^[[:space:]]*//' && echo -n '##>' | sed 's/##/"/g'`, backupdir)
bash = bash + fmt.Sprintf(`&&find %s -type f -exec sh -c 'echo $(stat -f "%%m" "$1") $(basename "$1") $(stat -f "%%z" "$1") $(md5sum "$1")' sh {} \; | sort -nr -k1`, backupdir)
bash = bash + `| awk '{ date = strftime("%Y-%m-%dT%H:%M:%S", $1); delta = systime() - $1; days = int(delta / 86400); hours = int((delta % 86400) / 3600); minutes = int((delta % 3600) / 60); seconds = int(delta % 60); age = days "d " hours "h " minutes "m " seconds "s"; print " <" $2 " age=\"" age "\"><date>" date "</date><size>" $3 "</size><md5>" $4 "</md5></" $2 ">"; } END { print "</backups>"; }'`

backups := internal.ExecuteCmd(bash, host)

Expand Down
5 changes: 4 additions & 1 deletion cmd/compare.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,11 @@ var compareCmd = &cobra.Command{

internal.Checkos()
olddoc := internal.LoadXMLFile(oldconfig, host)
if olddoc == nil {
internal.Log(1,"failed to get data from %s",oldconfig)
}
newdoc := internal.LoadXMLFile(newconfig, host)
if newdoc.Root() == nil {
if newdoc == nil {
newdoc = olddoc
}
deltadoc := internal.DiffXML(olddoc, newdoc, true)
Expand Down
5 changes: 4 additions & 1 deletion cmd/discard.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,11 @@ Use the 'discard' command cautiously to avoid losing uncommitted changes.`,
internal.Checkos()

configdoc := internal.LoadXMLFile(configfile, host)
if configdoc == nil {
internal.Log(1,"failed to get data from %s",configfile)
}
stagingdoc := internal.LoadXMLFile(stagingfile, host)
if stagingdoc.Root() == nil {
if stagingdoc == nil {
stagingdoc = configdoc
}
path := "opnsense"
Expand Down
3 changes: 3 additions & 0 deletions cmd/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ var restoreCmd = &cobra.Command{
filename = "/conf/backup/"+filename
internal.Checkos()
configdoc := internal.LoadXMLFile(filename, host)
if configdoc == nil {
internal.Log(1,"failed to get data from %s",filename)
}
internal.Log(2, "Load %s into /conf/staging.xml.",filename)
internal.SaveXMLFile(stagingfile, configdoc, host, true)
fmt.Printf("The file %s has been loaded into /conf/staging.xml.\n", filename)
Expand Down
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

var (
Version string = "0.12.0"
Version string = "0.12.1"
verbose int
force bool
host string
Expand Down
5 changes: 4 additions & 1 deletion cmd/save.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,11 @@ var saveCmd = &cobra.Command{
filename = "/conf/backup/"+filename
internal.Checkos()
configdoc := internal.LoadXMLFile(configfile, host)
if configdoc == nil {
internal.Log(1,"failed to get data from %s",configfile)
}
internal.SaveXMLFile(filename, configdoc, host, false)
fmt.Printf("Copy of %s saved to %s\n", configfile, filename)
fmt.Printf("%s saved to %s\n", configfile, filename)
},
}

Expand Down
6 changes: 6 additions & 0 deletions cmd/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,15 @@ The XPath parameter offers node targeting, enabling you to navigate to the exact
internal.Checkos()

configdoc := internal.LoadXMLFile(configfile, host)
if configdoc == nil {
internal.Log(1,"failed to get data from %s",configfile)
}
internal.EnumerateListElements(configdoc.Root())

stagingdoc := internal.LoadXMLFile(stagingfile, host)
if stagingdoc == nil {
stagingdoc = configdoc
}
internal.EnumerateListElements(stagingdoc.Root())

if stagingdoc.Root() == nil {
Expand Down
5 changes: 4 additions & 1 deletion cmd/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,11 @@ var showCmd = &cobra.Command{
internal.Checkos()

configdoc := internal.LoadXMLFile(configfile, host)
if configdoc == nil {
internal.Log(1,"failed to get data from %s",configfile)
}
stagingdoc := internal.LoadXMLFile(stagingfile, host)
if stagingdoc.Root() == nil {
if stagingdoc == nil {
stagingdoc = configdoc
}

Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/Microsoft/go-winio v0.6.1
github.com/beevik/etree v1.2.0
github.com/clbanning/mxj v1.8.4
github.com/pkg/sftp v1.13.6
github.com/spf13/cobra v1.7.0
golang.org/x/crypto v0.11.0
golang.org/x/term v0.10.0
Expand All @@ -14,6 +15,7 @@ require (

require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/mod v0.12.0 // indirect
golang.org/x/sys v0.10.0 // indirect
Expand Down
43 changes: 43 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,68 @@ github.com/beevik/etree v1.2.0/go.mod h1:aiPf89g/1k3AShMVAzriilpcE4R/Vuor90y83zV
github.com/clbanning/mxj v1.8.4 h1:HuhwZtbyvyOw+3Z1AowPkU87JkJUSv751ELWaiTpj8I=
github.com/clbanning/mxj v1.8.4/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo=
github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.11.1 h1:ojD5zOW8+7dOGzdnNgersm8aPfcDjhMp12UfG93NIMc=
golang.org/x/tools v0.11.1/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
2 changes: 1 addition & 1 deletion internal/checkos.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (

func Checkos() (string, error) {
//check that the target is OPNsense
osstr := ExecuteCmd("echo $(uname; opnsense-version -N)", host)
osstr := ExecuteCmd("echo `uname` `opnsense-version -N`", host)
osstr = strings.TrimSpace(osstr)
if osstr != "FreeBSD OPNsense" {
Log(1, "%s is not OPNsense system", osstr)
Expand Down
11 changes: 6 additions & 5 deletions internal/eTreeRender.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,16 @@ import (

func FocusEtree(doc *etree.Document, path string) *etree.Element {
foundElements := doc.FindElements(path)
foundElement := foundElements[len(foundElements)-1]
if foundElement == nil {
if len(foundElements) == 0 {
Log(1, "Xpath element \"%s\" does not exist", path)
return nil
}
//fmt.Println(path, "elements: ", len(foundElements))

parts := strings.Split(path, "/")
focused := etree.NewElement(parts[0])

// Get the space of the found element
space := foundElement.Space
space := foundElements[0].Space
depth := len(parts)
if depth > 1 {
parts = parts[:depth-1]
Expand All @@ -41,7 +39,10 @@ func FocusEtree(doc *etree.Document, path string) *etree.Element {
}
current = newElem
}
current.AddChild(foundElement.Copy())
// Add all found elements
for _, foundElement := range foundElements {
current.AddChild(foundElement.Copy())
}
} else {
focused = doc.Root()
}
Expand Down
Loading

0 comments on commit cadbd2d

Please sign in to comment.