Skip to content

Commit

Permalink
feat: E2E example with static files required to execute it (#46)
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastianczech authored Apr 4, 2024
1 parent ba3131c commit f4e4c00
Show file tree
Hide file tree
Showing 74 changed files with 7,389 additions and 27 deletions.
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,14 @@ This command can be parametrizes using options:
- `mktp` - create only Terraform provider
- `mksdk` - create only PAN-OS SDK
- `config` - specify path for the config file, default is `cmd/codegen/config.yaml`


## Generate SDK

In order to use generated SDK code, go to directory defined in `config.yaml` e.g. `../generated/pango` and execute
example code:

```
go run cmd/codegen/main.go -t mksdk
cd ../generated/pango
PANOS_HOSTNAME='***' PANOS_USERNAME='***' PANOS_PASSWORD='***' go run example/main.go
```
142 changes: 142 additions & 0 deletions assets/errors/panos.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package errors

import (
"encoding/xml"
stderr "errors"
"fmt"
"strings"

"github.com/PaloAltoNetworks/pango/util"
)

var InvalidFilterError = stderr.New("filter is improperly formatted")
var NameNotSpecifiedError = stderr.New("name is not specified")
var NoLocationSpecifiedError = stderr.New("no location specified")
var RelativePositionWithRemoveEverythingElseError = stderr.New("cannot do relative positioning when removing all other rules")
var UnrecognizedOperatorError = stderr.New("unsupported filter operator")
var UnsupportedFilterTypeError = stderr.New("unsupported type for filtering")
var UuidNotSpecifiedError = stderr.New("uuid is not specified")

// Panos is an error returned from PAN-OS.
//
// The error contains both the error message and the code returned from PAN-OS.
type Panos struct {
Msg string
Code int
}

// Error returns the error message.
func (e Panos) Error() string {
return e.Msg
}

// ObjectNotFound returns true if this is an object not found error.
func (e Panos) ObjectNotFound() bool {
return e.Code == 7
}

// ObjectNotFound returns an object not found error.
func ObjectNotFound() Panos {
return Panos{
Msg: "Object not found",
Code: 7,
}
}

// Parse attempts to parse an error from the given XML response.
func Parse(body []byte) error {
var e errorCheck

_ = xml.Unmarshal(body, &e)
if e.Failed() {
return Panos{
Msg: e.Message(),
Code: e.Code,
}
}

return nil
}

type errorCheck struct {
XMLName xml.Name `xml:"response"`
Status string `xml:"status,attr"`
Code int `xml:"code,attr"`
Msg *errorCheckMsg `xml:"msg"`
ResultMsg *string `xml:"result>msg"`
}

type errorCheckMsg struct {
Line []util.CdataText `xml:"line"`
Message string `xml:",chardata"`
}

func (e *errorCheck) Failed() bool {
if e.Status == "failed" || e.Status == "error" {
return true
} else if e.Code == 0 || e.Code == 19 || e.Code == 20 {
return false
}

return true
}

func (e *errorCheck) Message() string {
if e.Msg != nil {
if len(e.Msg.Line) > 0 {
var b strings.Builder
for i := range e.Msg.Line {
if i != 0 {
b.WriteString(" | ")
}
b.WriteString(strings.TrimSpace(e.Msg.Line[i].Text))
}
return b.String()
}

if e.Msg.Message != "" {
return e.Msg.Message
}
}

if e.ResultMsg != nil {
return *e.ResultMsg
}

return e.CodeError()
}

func (e *errorCheck) CodeError() string {
switch e.Code {
case 1:
return "Unknown command"
case 2, 3, 4, 5, 11:
return fmt.Sprintf("Internal error (%d) encountered", e.Code)
case 6:
return "Bad Xpath"
case 7:
return "Object not found"
case 8:
return "Object not unique"
case 10:
return "Reference count not zero"
case 12:
return "Invalid object"
case 14:
return "Operation not possible"
case 15:
return "Operation denied"
case 16:
return "Unauthorized"
case 17:
return "Invalid command"
case 18:
return "Malformed command"
case 0, 19, 20:
return ""
case 22:
return "Session timed out"
default:
return fmt.Sprintf("(%d) Unknown failure code, operation failed", e.Code)
}
}
73 changes: 73 additions & 0 deletions assets/errors/panos_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package errors

import (
"fmt"
"strings"
"testing"
)

func TestGetSingularMissingObjectIsError(t *testing.T) {
data := `<response status="success" code="7"><result/></response>`

err := Parse([]byte(data))
if err == nil {
t.Errorf("Error is nil")
} else {
e2, ok := err.(Panos)
if !ok {
t.Errorf("Not a panos error")
} else if !e2.ObjectNotFound() {
t.Errorf("Not an object not found error")
}
}
}

func TestShowSingularMissingObjectIsError(t *testing.T) {
data := `<response status="error"><msg><line>No such node</line></msg></response>`

err := Parse([]byte(data))
if err == nil {
t.Errorf("Error is nil")
} else {
e2, ok := err.(Panos)
if !ok {
t.Errorf("Not a panos error")
} else if e2.Msg != "No such node" {
t.Errorf("Incorrect msg: %s", e2.Msg)
}
}
}

func TestMultilineErrorMessage(t *testing.T) {
expected := "HTTP method must be GET"
data := fmt.Sprintf(`<response status="error" code="12"><msg><line><![CDATA[ tf123456 -> server -> first server is invalid. %s, Username/Password must not be empty when Tag Distribution is chosen]]></line><line><![CDATA[ tf123456 -> server is invalid]]></line></msg></response>`, expected)

err := Parse([]byte(data))
if err == nil {
t.Errorf("Error is nil")
} else {
e2, ok := err.(Panos)
if !ok {
t.Errorf("Not a panos error")
} else if !strings.Contains(e2.Msg, expected) {
t.Errorf("Does not contain the expected substring: %s", e2.Msg)
}
}
}

func TestFailedExportErrorMessage(t *testing.T) {
expected := `Parameter "format" is required while exporting certificate`
data := `<response status = 'error' code = '400'><result><msg>Parameter &quot;format&quot; is required while exporting certificate</msg></result></response>`

err := Parse([]byte(data))
if err == nil {
t.Errorf("Error is nil")
} else {
e2, ok := err.(Panos)
if !ok {
t.Errorf("Not a pnos error")
} else if !strings.Contains(e2.Msg, expected) {
t.Errorf("Does not contain the expected substring: %s", e2.Msg)
}
}
}
Loading

0 comments on commit f4e4c00

Please sign in to comment.