-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: E2E example with static files required to execute it (#46)
- Loading branch information
1 parent
ba3131c
commit f4e4c00
Showing
74 changed files
with
7,389 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 "format" 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) | ||
} | ||
} | ||
} |
Oops, something went wrong.