diff --git a/assets/errors/panos.go b/assets/errors/panos.go deleted file mode 100644 index b56e8c49..00000000 --- a/assets/errors/panos.go +++ /dev/null @@ -1,140 +0,0 @@ -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 UnrecognizedOperatorError = stderr.New("unsupported filter operator") -var UnsupportedFilterTypeError = stderr.New("unsupported type for filtering") - -// 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) - } -} diff --git a/assets/errors/panos_test.go b/assets/errors/panos_test.go deleted file mode 100644 index 70f07dcf..00000000 --- a/assets/errors/panos_test.go +++ /dev/null @@ -1,73 +0,0 @@ -package errors - -import ( - "fmt" - "strings" - "testing" -) - -func TestGetSingularMissingObjectIsError(t *testing.T) { - data := `` - - 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 := `No such node` - - 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(` server -> first server is invalid. %s, Username/Password must not be empty when Tag Distribution is chosen]]> server is invalid]]>`, 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 := `Parameter "format" is required while exporting certificate` - - 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) - } - } -} diff --git a/assets/util/actioner.go b/assets/util/actioner.go deleted file mode 100644 index 0b516835..00000000 --- a/assets/util/actioner.go +++ /dev/null @@ -1,5 +0,0 @@ -package util - -type Actioner interface { - Action() string -} diff --git a/assets/util/bulk_element.go b/assets/util/bulk_element.go deleted file mode 100644 index 5a129757..00000000 --- a/assets/util/bulk_element.go +++ /dev/null @@ -1,19 +0,0 @@ -package util - -import ( - "encoding/xml" -) - -// BulkElement is a generic bulk container for bulk operations. -type BulkElement struct { - XMLName xml.Name - Data []interface{} -} - -// Config returns an interface to be Marshaled. -func (o BulkElement) Config() interface{} { - if len(o.Data) == 1 { - return o.Data[0] - } - return o -} diff --git a/assets/util/comparison.go b/assets/util/comparison.go deleted file mode 100644 index e5c164b7..00000000 --- a/assets/util/comparison.go +++ /dev/null @@ -1,76 +0,0 @@ -package util - -func UnorderedListsMatch(a, b []string) bool { - if a == nil && b == nil { - return true - } else if a == nil || b == nil { - return false - } else if len(a) != len(b) { - return false - } - - for _, x := range a { - var found bool - for _, y := range b { - if x == y { - found = true - break - } - } - if !found { - return false - } - } - - return true -} - -func OrderedListsMatch(a, b []string) bool { - if a == nil && b == nil { - return true - } else if a == nil || b == nil { - return false - } else if len(a) != len(b) { - return false - } - - for i := range a { - if a[i] != b[i] { - return false - } - } - - return true -} - -func TargetsMatch(a, b map[string][]string) bool { - if a == nil && b == nil { - return true - } else if a == nil || b == nil { - return false - } else if len(a) != len(b) { - return false - } - - for key := range a { - if !UnorderedListsMatch(a[key], b[key]) { - return false - } - } - - return true -} - -func OptionalStringsMatch(a, b *string) bool { - if a == nil && b == nil { - return true - } else if a == nil || b == nil { - return false - } - - return *a == *b -} - -func StringsMatch(a, b string) bool { - return a == b -} diff --git a/assets/util/const.go b/assets/util/const.go deleted file mode 100644 index c5a6a729..00000000 --- a/assets/util/const.go +++ /dev/null @@ -1,39 +0,0 @@ -package util - -// Rulebase constants for various policies. -const ( - Rulebase = "rulebase" - PreRulebase = "pre-rulebase" - PostRulebase = "post-rulebase" -) - -// Valid values to use for VsysImport() or VsysUnimport(). -const ( - InterfaceImport = "interface" - VirtualRouterImport = "virtual-router" - VirtualWireImport = "virtual-wire" - VlanImport = "vlan" -) - -// These constants are valid move locations to pass to various movement -// functions (aka - policy management). -const ( - MoveSkip = iota - MoveBefore - MoveDirectlyBefore - MoveAfter - MoveDirectlyAfter - MoveTop - MoveBottom -) - -// Valid values to use for any function expecting a pango query type `qt`. -const ( - Get = "get" - Show = "show" -) - -// PanosTimeWithoutTimezoneFormat is a time (missing the timezone) that PAN-OS -// will give sometimes. Combining this with `Clock()` to get a usable time. -// report that does not contain -const PanosTimeWithoutTimezoneFormat = "2006/01/02 15:04:05" diff --git a/assets/util/copy.go b/assets/util/copy.go deleted file mode 100644 index 6a7765cd..00000000 --- a/assets/util/copy.go +++ /dev/null @@ -1,31 +0,0 @@ -package util - -func CopyStringSlice(v []string) []string { - if v == nil { - return nil - } - - ans := make([]string, len(v)) - copy(ans, v) - - return ans -} - -func CopyTargets(v map[string][]string) map[string][]string { - if v == nil { - return nil - } - - ans := make(map[string][]string) - for key, oval := range v { - if oval == nil { - ans[key] = nil - } else { - val := make([]string, len(oval)) - copy(val, oval) - ans[key] = val - } - } - - return ans -} diff --git a/assets/util/elementer.go b/assets/util/elementer.go deleted file mode 100644 index 72688d67..00000000 --- a/assets/util/elementer.go +++ /dev/null @@ -1,6 +0,0 @@ -package util - -// Elementer is an interface for commits. -type Elementer interface { - Element() interface{} -} diff --git a/assets/util/entry.go b/assets/util/entry.go deleted file mode 100644 index 0c1ea4c9..00000000 --- a/assets/util/entry.go +++ /dev/null @@ -1,67 +0,0 @@ -package util - -import ( - "encoding/xml" -) - -// EntryType defines an entry config node used for sending and receiving XML -// from PAN-OS. -type EntryType struct { - Entries []Entry `xml:"entry"` -} - -// Entry is a standalone entry struct. -type Entry struct { - XMLName xml.Name `xml:"entry"` - Value string `xml:"name,attr"` -} - -// EntToStr normalizes an EntryType pointer into a list of strings. -func EntToStr(e *EntryType) []string { - if e == nil { - return nil - } - - ans := make([]string, len(e.Entries)) - for i := range e.Entries { - ans[i] = e.Entries[i].Value - } - - return ans -} - -// StrToEnt converts a list of strings into an EntryType pointer. -func StrToEnt(e []string) *EntryType { - if e == nil { - return nil - } - - ans := make([]Entry, len(e)) - for i := range e { - ans[i] = Entry{Value: e[i]} - } - - return &EntryType{ans} -} - -// EntToOneStr normalizes an EntryType pointer for a max_items=1 XML node -// into a string. -func EntToOneStr(e *EntryType) string { - if e == nil || len(e.Entries) == 0 { - return "" - } - - return e.Entries[0].Value -} - -// OneStrToEnt converts a string into an EntryType pointer for a max_items=1 -// XML node. -func OneStrToEnt(e string) *EntryType { - if e == "" { - return nil - } - - return &EntryType{[]Entry{ - {Value: e}, - }} -} diff --git a/assets/util/hitcount.go b/assets/util/hitcount.go deleted file mode 100644 index d10e7f77..00000000 --- a/assets/util/hitcount.go +++ /dev/null @@ -1,67 +0,0 @@ -package util - -import ( - "encoding/xml" -) - -// NewHitCountRequest returns a new hit count request struct. -// -// If the rules param is nil, then the hit count for all rules is returned. -func NewHitCountRequest(rulebase, vsys string, rules []string) interface{} { - req := hcReq{ - Vsys: hcReqVsys{ - Name: vsys, - Rulebase: hcReqRulebase{ - Name: rulebase, - Rules: hcReqRules{ - List: StrToMem(rules), - }, - }, - }, - } - - if req.Vsys.Rulebase.Rules.List == nil { - s := "" - req.Vsys.Rulebase.Rules.All = &s - } - - return req -} - -// HitCountResponse is the hit count response struct. -type HitCountResponse struct { - XMLName xml.Name `xml:"response"` - Results []HitCount `xml:"result>rule-hit-count>vsys>entry>rule-base>entry>rules>entry"` -} - -// HitCount is the hit count data for a specific rule. -type HitCount struct { - Name string `xml:"name,attr"` - Latest string `xml:"latest"` - HitCount uint `xml:"hit-count"` - LastHitTimestamp int `xml:"last-hit-timestamp"` - LastResetTimestamp int `xml:"last-reset-timestamp"` - FirstHitTimestamp int `xml:"first-hit-timestamp"` - RuleCreationTimestamp int `xml:"rule-creation-timestamp"` - RuleModificationTimestamp int `xml:"rule-modification-timestamp"` -} - -type hcReq struct { - XMLName xml.Name `xml:"show"` - Vsys hcReqVsys `xml:"rule-hit-count>vsys>vsys-name>entry"` -} - -type hcReqVsys struct { - Name string `xml:"name,attr"` - Rulebase hcReqRulebase `xml:"rule-base>entry"` -} - -type hcReqRulebase struct { - Name string `xml:"name,attr"` - Rules hcReqRules `xml:"rules"` -} - -type hcReqRules struct { - All *string `xml:"all"` - List *MemberType `xml:"list"` -} diff --git a/assets/util/jobs.go b/assets/util/jobs.go deleted file mode 100644 index e3b9ca63..00000000 --- a/assets/util/jobs.go +++ /dev/null @@ -1,71 +0,0 @@ -package util - -import ( - "encoding/xml" - "strconv" - "strings" -) - -// JobResponse parses a XML response that includes a job ID. -type JobResponse struct { - XMLName xml.Name `xml:"response"` - Id uint `xml:"result>job"` -} - -// BasicJob is a struct for parsing minimal information about a submitted -// job to PANOS. -type BasicJob struct { - XMLName xml.Name `xml:"response"` - Result string `xml:"result>job>result"` - Progress uint `xml:"-"` - Details BasicJobDetails `xml:"result>job>details"` - Devices []devJob `xml:"result>job>devices>entry"` - Status string `xml:"result>job>status"` // For log retrieval jobs. - ProgressRaw string `xml:"result>job>progress"` -} - -func (o *BasicJob) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - type localBasicJob BasicJob - var ans localBasicJob - if err := d.DecodeElement(&ans, &start); err != nil { - return err - } - - val, err := strconv.ParseUint(strings.TrimSpace(ans.ProgressRaw), 10, 32) - if err == nil { - ans.Progress = uint(val) - } - - *o = BasicJob(ans) - return nil -} - -type BasicJobDetails struct { - Lines []LineOrCdata `xml:"line"` -} - -func (o *BasicJobDetails) String() string { - ans := make([]string, 0, len(o.Lines)) - - for _, line := range o.Lines { - if line.Cdata != nil { - ans = append(ans, strings.TrimSpace(*line.Cdata)) - } else if line.Text != nil { - ans = append(ans, *line.Text) - } else { - ans = append(ans, "huh") - } - } - - return strings.Join(ans, " | ") -} - -type LineOrCdata struct { - Cdata *string `xml:",cdata"` - Text *string `xml:",chardata"` -} - -type devJob struct { - Serial string `xml:"serial-no"` - Result string `xml:"result"` -} diff --git a/assets/util/license.go b/assets/util/license.go deleted file mode 100644 index 5bd7f44f..00000000 --- a/assets/util/license.go +++ /dev/null @@ -1,17 +0,0 @@ -package util - -import ( - "encoding/xml" -) - -// License defines a license entry. -type License struct { - XMLName xml.Name `xml:"entry"` - Feature string `xml:"feature"` - Description string `xml:"description"` - Serial string `xml:"serial"` - Issued string `xml:"issued"` - Expires string `xml:"expires"` - Expired string `xml:"expired"` - AuthCode string `xml:"authcode"` -} diff --git a/assets/util/lock.go b/assets/util/lock.go deleted file mode 100644 index 1e819c2f..00000000 --- a/assets/util/lock.go +++ /dev/null @@ -1,15 +0,0 @@ -package util - -import ( - "encoding/xml" -) - -// Lock represents either a config lock or a commit lock. -type Lock struct { - XMLName xml.Name `xml:"entry"` - Owner string `xml:"name,attr"` - Name string `xml:"name"` - Type string `xml:"type"` - LoggedIn string `xml:"loggedin"` - Comment CdataText `xml:"comment"` -} diff --git a/assets/util/member.go b/assets/util/member.go deleted file mode 100644 index 658cbb0c..00000000 --- a/assets/util/member.go +++ /dev/null @@ -1,68 +0,0 @@ -package util - -import ( - "encoding/xml" -) - -// MemberType defines a member config node used for sending and receiving XML -// from PAN-OS. -type MemberType struct { - Members []Member `xml:"member"` -} - -// Member defines a member config node used for sending and receiving XML -// from PANOS. -type Member struct { - XMLName xml.Name `xml:"member"` - Value string `xml:",chardata"` -} - -// MemToStr normalizes a MemberType pointer into a list of strings. -func MemToStr(e *MemberType) []string { - if e == nil { - return nil - } - - ans := make([]string, len(e.Members)) - for i := range e.Members { - ans[i] = e.Members[i].Value - } - - return ans -} - -// StrToMem converts a list of strings into a MemberType pointer. -func StrToMem(e []string) *MemberType { - if e == nil { - return nil - } - - ans := make([]Member, len(e)) - for i := range e { - ans[i] = Member{Value: e[i]} - } - - return &MemberType{ans} -} - -// MemToOneStr normalizes a MemberType pointer for a max_items=1 XML node -// into a string. -func MemToOneStr(e *MemberType) string { - if e == nil || len(e.Members) == 0 { - return "" - } - - return e.Members[0].Value -} - -// OneStrToMem converts a string into a MemberType pointer for a max_items=1 -// XML node. -func OneStrToMem(e string) *MemberType { - if e == "" { - return nil - } - - return &MemberType{[]Member{ - {Value: e}, - }} -} diff --git a/assets/util/pangoclient.go b/assets/util/pangoclient.go deleted file mode 100644 index 0f2a3338..00000000 --- a/assets/util/pangoclient.go +++ /dev/null @@ -1,21 +0,0 @@ -package util - -import ( - "context" - "net/http" - "net/url" - - "github.com/PaloAltoNetworks/pango/plugin" - "github.com/PaloAltoNetworks/pango/version" - "github.com/PaloAltoNetworks/pango/xmlapi" -) - -type PangoClient interface { - Versioning() version.Number - GetTarget() string - Plugins() []plugin.Info - MultiConfig(context.Context, *xmlapi.MultiConfig, bool, url.Values) ([]byte, *http.Response, *xmlapi.MultiConfigResponse, error) - Communicate(context.Context, PangoCommand, bool, any) ([]byte, *http.Response, error) - CommunicateFile(context.Context, string, string, string, url.Values, bool, any) ([]byte, *http.Response, error) - ReadFromConfig(context.Context, []string, bool, any) ([]byte, error) -} diff --git a/assets/util/pangocommand.go b/assets/util/pangocommand.go deleted file mode 100644 index 362c2f3b..00000000 --- a/assets/util/pangocommand.go +++ /dev/null @@ -1,9 +0,0 @@ -package util - -import ( - "net/url" -) - -type PangoCommand interface { - AsUrlValues() (url.Values, error) -} diff --git a/assets/util/retriever.go b/assets/util/retriever.go deleted file mode 100644 index 4d4c1459..00000000 --- a/assets/util/retriever.go +++ /dev/null @@ -1,5 +0,0 @@ -package util - -// Retriever is a type that is intended to act as a stand-in for using -// either the Get or Show pango Client functions. -type Retriever func(interface{}, interface{}, interface{}) ([]byte, error) diff --git a/assets/util/util.go b/assets/util/util.go deleted file mode 100644 index 2a21a3e3..00000000 --- a/assets/util/util.go +++ /dev/null @@ -1,282 +0,0 @@ -// Package util contains various shared structs and functions used across -// the pango package. -package util - -import ( - "bytes" - "encoding/xml" - "fmt" - "regexp" - "strings" -) - -// VsysEntryType defines an entry config node with vsys entries underneath. -type VsysEntryType struct { - Entries []VsysEntry `xml:"entry"` -} - -// VsysEntry defines the "vsys" xpath node under a VsysEntryType config node. -type VsysEntry struct { - XMLName xml.Name `xml:"entry"` - Serial string `xml:"name,attr"` - Vsys *EntryType `xml:"vsys"` -} - -// VsysEntToMap normalizes a VsysEntryType pointer into a map. -func VsysEntToMap(ve *VsysEntryType) map[string][]string { - if ve == nil { - return nil - } - - ans := make(map[string][]string) - for i := range ve.Entries { - ans[ve.Entries[i].Serial] = EntToStr(ve.Entries[i].Vsys) - } - - return ans -} - -// MapToVsysEnt converts a map into a VsysEntryType pointer. -// -// This struct is used for "Target" information on Panorama when dealing with -// various policies. Maps are unordered, but FWICT Panorama doesn't seem to -// order anything anyways when doing things in the GUI, so hopefully this is -// ok...? -func MapToVsysEnt(e map[string][]string) *VsysEntryType { - if len(e) == 0 { - return nil - } - - i := 0 - ve := make([]VsysEntry, len(e)) - for key := range e { - ve[i].Serial = key - ve[i].Vsys = StrToEnt(e[key]) - i++ - } - - return &VsysEntryType{ve} -} - -// YesNo returns "yes" on true, "no" on false. -func YesNo(v bool) string { - if v { - return "yes" - } - return "no" -} - -// AsBool returns true on yes, else false. -func AsBool(val string) bool { - if val == "yes" { - return true - } - return false -} - -// AsXpath makes an xpath out of the given interface. -func AsXpath(i interface{}) string { - switch val := i.(type) { - case string: - return val - case []string: - return fmt.Sprintf("/%s", strings.Join(val, "/")) - default: - return "" - } -} - -// AsEntryXpath returns the given values as an entry xpath segment. -func AsEntryXpath(vals []string) string { - if len(vals) == 0 || (len(vals) == 1 && vals[0] == "") { - return "entry" - } - - var buf bytes.Buffer - - buf.WriteString("entry[") - for i := range vals { - if i != 0 { - buf.WriteString(" or ") - } - buf.WriteString("@name='") - buf.WriteString(vals[i]) - buf.WriteString("'") - } - buf.WriteString("]") - - return buf.String() -} - -// AsMemberXpath returns the given values as a member xpath segment. -func AsMemberXpath(vals []string) string { - var buf bytes.Buffer - - buf.WriteString("member[") - for i := range vals { - if i != 0 { - buf.WriteString(" or ") - } - buf.WriteString("text()='") - buf.WriteString(vals[i]) - buf.WriteString("'") - } - - buf.WriteString("]") - - return buf.String() -} - -// TemplateXpathPrefix returns the template xpath prefix of the given template name. -func TemplateXpathPrefix(tmpl, ts string) []string { - if tmpl != "" { - return []string{ - "config", - "devices", - AsEntryXpath([]string{"localhost.localdomain"}), - "template", - AsEntryXpath([]string{tmpl}), - } - } - - return []string{ - "config", - "devices", - AsEntryXpath([]string{"localhost.localdomain"}), - "template-stack", - AsEntryXpath([]string{ts}), - } -} - -// DeviceGroupXpathPrefix returns a device group xpath prefix. -// If the device group is empty, then the default is "shared". -func DeviceGroupXpathPrefix(dg string) []string { - if dg == "" || dg == "shared" { - return []string{"config", "shared"} - } - - return []string{ - "config", - "devices", - AsEntryXpath([]string{"localhost.localdomain"}), - "device-group", - AsEntryXpath([]string{dg}), - } -} - -// VsysXpathPrefix returns a vsys xpath prefix. -func VsysXpathPrefix(vsys string) []string { - if vsys == "" { - vsys = "vsys1" - } else if vsys == "shared" { - return []string{"config", "shared"} - } - - return []string{ - "config", - "devices", - AsEntryXpath([]string{"localhost.localdomain"}), - "vsys", - AsEntryXpath([]string{vsys}), - } -} - -// PanoramaXpathPrefix returns the panorama xpath prefix. -func PanoramaXpathPrefix() []string { - return []string{ - "config", - "panorama", - } -} - -// StripPanosPackaging removes the response / result and an optional third -// containing XML tag from the given byte slice. -func StripPanosPackaging(input []byte, tag string) []byte { - var index int - gt := []byte(">") - lt := []byte("<") - - // Remove response. - index = bytes.Index(input, gt) - ans := input[index+1:] - index = bytes.LastIndex(ans, lt) - ans = ans[:index] - - // Remove result. - index = bytes.Index(ans, gt) - ans = ans[index+1:] - index = bytes.LastIndex(ans, lt) - ans = ans[:index] - - ans = bytes.TrimSpace(ans) - - if tag != "" { - if bytes.HasPrefix(ans, []byte("<"+tag+" ")) || bytes.HasPrefix(ans, []byte("<"+tag+">")) { - index = bytes.Index(ans, gt) - ans = ans[index+1:] - if len(ans) > 0 { - index = bytes.LastIndex(ans, lt) - ans = ans[:index] - ans = bytes.TrimSpace(ans) - } - } - } - - return ans -} - -// CdataText is for getting CDATA contents of XML docs. -type CdataText struct { - Text string `xml:",cdata"` -} - -// RawXml is what allows the use of Edit commands on a XPATH without -// truncating any other child objects that may be attached to it. -type RawXml struct { - Text string `xml:",innerxml"` -} - -// CleanRawXml removes extra XML attributes from RawXml objects without -// requiring us to have to parse everything. -func CleanRawXml(v string) string { - re := regexp.MustCompile(` admin="\S+" dirtyId="\d+" time="\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}"`) - return re.ReplaceAllString(v, "") -} - -// ValidMovement returns if the movement constant is valid or not. -func ValidMovement(v int) bool { - switch v { - case MoveSkip, MoveBefore, MoveDirectlyBefore, MoveAfter, MoveDirectlyAfter, MoveTop, MoveBottom: - return true - } - - return false -} - -// RelativeMovement returns if the movement constant is a relative movement. -func RelativeMovement(v int) bool { - switch v { - case MoveBefore, MoveDirectlyBefore, MoveAfter, MoveDirectlyAfter: - return true - } - - return false -} - -// ValidateRulebase validates the device group and rulebase pairing for -// Panorama policies. -func ValidateRulebase(dg, base string) error { - switch base { - case "": - return fmt.Errorf("rulebase must be specified") - case Rulebase: - if dg != "shared" { - return fmt.Errorf("rulebase %q requires \"shared\" device group", base) - } - case PreRulebase, PostRulebase: - default: - return fmt.Errorf("unknown rulebase %q", base) - } - - return nil -} diff --git a/assets/util/util_test.go b/assets/util/util_test.go deleted file mode 100644 index 08126d0d..00000000 --- a/assets/util/util_test.go +++ /dev/null @@ -1,224 +0,0 @@ -package util - -import ( - "bytes" - "fmt" - "testing" -) - -func TestMemToStrNil(t *testing.T) { - r := MemToStr(nil) - if r != nil { - t.Fail() - } -} - -func TestEntToStrNil(t *testing.T) { - r := EntToStr(nil) - if r != nil { - t.Fail() - } -} - -func TestStrToMem(t *testing.T) { - v := []string{"one", "two"} - r := StrToMem(v) - if r == nil { - t.Fail() - } else if len(v) != len(r.Members) { - t.Fail() - } else { - for i := range v { - if v[i] != r.Members[i].Value { - t.Fail() - break - } - } - } -} - -func TestStrToEnt(t *testing.T) { - v := []string{"one", "two"} - r := StrToEnt(v) - if r == nil { - t.Fail() - } else if len(v) != len(r.Entries) { - t.Fail() - } else { - for i := range v { - if v[i] != r.Entries[i].Value { - t.Fail() - break - } - } - } -} - -func BenchmarkStrToMem(b *testing.B) { - v := []string{"one", "two", "three", "four", "five"} - b.ResetTimer() - - for i := 0; i < b.N; i++ { - _ = StrToMem(v) - } -} - -func BenchmarkMemToStr(b *testing.B) { - m := &MemberType{[]Member{ - {Value: "one"}, - {Value: "two"}, - {Value: "three"}, - {Value: "four"}, - {Value: "five"}, - }} - b.ResetTimer() - - for i := 0; i < b.N; i++ { - _ = MemToStr(m) - } -} - -func BenchmarkStrToEnt(b *testing.B) { - v := []string{"one", "two", "three", "four", "five"} - b.ResetTimer() - - for i := 0; i < b.N; i++ { - _ = StrToEnt(v) - } -} - -func BenchmarkEntToStr(b *testing.B) { - v := &EntryType{[]Entry{ - {Value: "one"}, - {Value: "two"}, - {Value: "three"}, - {Value: "four"}, - {Value: "five"}, - }} - b.ResetTimer() - - for i := 0; i < b.N; i++ { - _ = EntToStr(v) - } -} - -func BenchmarkAsXpath(b *testing.B) { - p := []string{ - "config", - "devices", - AsEntryXpath([]string{"localhost.localdomain"}), - "vsys", - AsEntryXpath([]string{"vsys1"}), - "import", - "network", - } - b.ResetTimer() - - for i := 0; i < b.N; i++ { - _ = AsXpath(p) - } -} - -func BenchmarkAsEntryXpathMultiple(b *testing.B) { - v := []string{"one", "two", "three"} - b.ResetTimer() - - for i := 0; i < b.N; i++ { - _ = AsEntryXpath(v) - } -} - -func TestAsXpath(t *testing.T) { - testCases := []struct { - i interface{} - r string - }{ - {"/one/two", "/one/two"}, - {[]string{"one", "two"}, "/one/two"}, - {42, ""}, - } - - for _, tc := range testCases { - t.Run(fmt.Sprintf("%v to %s", tc.i, tc.r), func(t *testing.T) { - if AsXpath(tc.i) != tc.r { - t.Fail() - } - }) - } -} - -func TestAsEntryXpath(t *testing.T) { - testCases := []struct { - v []string - r string - }{ - {[]string{"one"}, "entry[@name='one']"}, - {[]string{"one", "two"}, "entry[@name='one' or @name='two']"}, - {nil, "entry"}, - } - - for _, tc := range testCases { - t.Run(tc.r, func(t *testing.T) { - if AsEntryXpath(tc.v) != tc.r { - t.Fail() - } - }) - } -} - -func TestAsMemberXpath(t *testing.T) { - testCases := []struct { - v []string - r string - }{ - {[]string{"one"}, "member[text()='one']"}, - {[]string{"one", "two"}, "member[text()='one' or text()='two']"}, - {nil, "member[]"}, - } - - for _, tc := range testCases { - t.Run(tc.r, func(t *testing.T) { - if AsMemberXpath(tc.v) != tc.r { - t.Fail() - } - }) - } -} - -func TestCleanRawXml(t *testing.T) { - v := `hi` - if CleanRawXml(v) != "hi" { - t.Fail() - } -} - -func TestStripPanosPackagingNoTag(t *testing.T) { - expected := "" - input := fmt.Sprintf("%s", expected) - - ans := StripPanosPackaging([]byte(input), "") - if !bytes.Equal([]byte(expected), ans) { - t.Errorf("Expected %q, got %q", expected, ans) - } -} - -func TestStripPanosPackagingWithTag(t *testing.T) { - expected := "" - input := fmt.Sprintf("%s", expected) - - ans := StripPanosPackaging([]byte(input), "outer") - if !bytes.Equal([]byte(expected), ans) { - t.Errorf("Expected %q, got %q", expected, ans) - } -} - -func TestStripPanosPackagingNoResult(t *testing.T) { - input := ` - -` - - ans := StripPanosPackaging([]byte(input), "interface") - if len(ans) != 0 { - t.Errorf("Expected empty string, got %q", ans) - } -} diff --git a/assets/util/xapiclient.go b/assets/util/xapiclient.go deleted file mode 100644 index 992d21b7..00000000 --- a/assets/util/xapiclient.go +++ /dev/null @@ -1,52 +0,0 @@ -package util - -import ( - "time" - - "github.com/PaloAltoNetworks/pango/plugin" - "github.com/PaloAltoNetworks/pango/version" -) - -// XapiClient is the interface that describes an pango.Client. -type XapiClient interface { - String() string - Versioning() version.Number - Plugins() []plugin.Info - - // Logging functions. - LogAction(string, ...interface{}) - LogQuery(string, ...interface{}) - LogOp(string, ...interface{}) - LogUid(string, ...interface{}) - LogLog(string, ...interface{}) - LogExport(string, ...interface{}) - LogImport(string, ...interface{}) - - // PAN-OS API calls. - Op(interface{}, string, interface{}, interface{}) ([]byte, error) - Show(interface{}, interface{}, interface{}) ([]byte, error) - Get(interface{}, interface{}, interface{}) ([]byte, error) - Delete(interface{}, interface{}, interface{}) ([]byte, error) - Set(interface{}, interface{}, interface{}, interface{}) ([]byte, error) - Edit(interface{}, interface{}, interface{}, interface{}) ([]byte, error) - Move(interface{}, string, string, interface{}, interface{}) ([]byte, error) - Log(string, string, string, string, int, int, interface{}, interface{}) ([]byte, error) - Export(string, time.Duration, interface{}, interface{}) (string, []byte, error) - Import(string, string, string, string, time.Duration, interface{}, interface{}) ([]byte, error) - Commit(interface{}, string, interface{}) (uint, []byte, error) - Uid(interface{}, string, interface{}, interface{}) ([]byte, error) - - // Vsys importables. - VsysImport(string, string, string, string, []string) error - VsysUnimport(string, string, string, []string) error - - // Extras. - EntryListUsing(Retriever, []string) ([]string, error) - MemberListUsing(Retriever, []string) ([]string, error) - RequestPasswordHash(string) (string, error) - WaitForJob(uint, time.Duration, interface{}, interface{}) error - WaitForLogs(uint, time.Duration, time.Duration, interface{}) ([]byte, error) - Clock() (time.Time, error) - PositionFirstEntity(int, string, string, []string, []string) error - ConfigTree() *XmlNode -} diff --git a/assets/util/xmlnode.go b/assets/util/xmlnode.go deleted file mode 100644 index f6f3410d..00000000 --- a/assets/util/xmlnode.go +++ /dev/null @@ -1,54 +0,0 @@ -package util - -import ( - "encoding/xml" - "strings" -) - -const ( - entryPrefix = "entry[@name='" - entrySuffix = "']" -) - -// XmlNode is a generic XML node. -type XmlNode struct { - XMLName xml.Name - Attributes []xml.Attr `xml:",any,attr"` - Text []byte `xml:",innerxml"` - Nodes []XmlNode `xml:",any"` -} - -// FindXmlNodeInTree finds a given path in the specified XmlNode tree. -func FindXmlNodeInTree(path []string, elm *XmlNode) *XmlNode { - if len(path) == 0 { - return elm - } - - if elm == nil { - return elm - } - - tag := path[0] - path = path[1:] - var name string - if strings.HasPrefix(tag, entryPrefix) { - name = strings.TrimSuffix(strings.TrimPrefix(tag, entryPrefix), entrySuffix) - tag = "entry" - } - - for _, x := range elm.Nodes { - if x.XMLName.Local == tag { - if name == "" { - return FindXmlNodeInTree(path, &x) - } else { - for _, atr := range x.Attributes { - if atr.Name.Local == "name" && atr.Value == name { - return FindXmlNodeInTree(path, &x) - } - } - } - } - } - - return nil -} diff --git a/assets/version/version.go b/assets/version/version.go deleted file mode 100644 index b982d9d1..00000000 --- a/assets/version/version.go +++ /dev/null @@ -1,72 +0,0 @@ -// Package version contains a version number struct that pango uses to make -// decisions on the specific structs to use when sending XML to the PANOS -// device. -package version - -import ( - "fmt" - "strconv" - "strings" -) - -// Number is the version number struct. -type Number struct { - Major, Minor, Patch int - Suffix string -} - -// Gte tests if this version number is greater than or equal to the argument. -func (v Number) Gte(o Number) bool { - if v.Major != o.Major { - return v.Major > o.Major - } - - if v.Minor != o.Minor { - return v.Minor > o.Minor - } - - return v.Patch >= o.Patch -} - -// String returns the version number as a string. -func (v Number) String() string { - if v.Suffix == "" { - return fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch) - } else { - return fmt.Sprintf("%d.%d.%d-%s", v.Major, v.Minor, v.Patch, v.Suffix) - } -} - -// New returns a version number from the given string. -func New(version string) (Number, error) { - parts := strings.Split(version, ".")[:3] - - major, err := strconv.Atoi(parts[0]) - if err != nil { - return Number{}, fmt.Errorf("Major %s is not a number: %s", parts[0], err) - } - - minor, err := strconv.Atoi(parts[1]) - if err != nil { - return Number{}, fmt.Errorf("Minor %s is not a number: %s", parts[0], err) - } - - var patch_str string - var suffix string - patch_parts := strings.Split(parts[2], "-") - if len(patch_parts) == 1 { - patch_str = parts[2] - suffix = "" - } else if len(patch_parts) == 2 { - patch_str = patch_parts[0] - suffix = patch_parts[1] - } else { - return Number{}, fmt.Errorf("Patch %s is not formatted as expected", parts[2]) - } - patch, err := strconv.Atoi(patch_str) - if err != nil { - return Number{}, fmt.Errorf("Patch %s is not a number: %s", patch_str, err) - } - - return Number{major, minor, patch, suffix}, nil -} diff --git a/assets/version/version_test.go b/assets/version/version_test.go deleted file mode 100644 index 547d5aa3..00000000 --- a/assets/version/version_test.go +++ /dev/null @@ -1,124 +0,0 @@ -package version - -import ( - "fmt" - "testing" -) - -func TestNew(t *testing.T) { - testCases := []struct { - s string - r bool - a, b, c int - d string - }{ - {"1.2.3", false, 1, 2, 3, ""}, - {"1.2.3-h4", false, 1, 2, 3, "h4"}, - {"12.34.56-78h", false, 12, 34, 56, "78h"}, - {"a.2.3", true, 0, 0, 0, ""}, - {"1.b.3", true, 0, 0, 0, ""}, - {"1.2.c", true, 0, 0, 0, ""}, - {"1.2.3h4", true, 0, 0, 0, ""}, - {"9.0.3.xfr", false, 9, 0, 3, ""}, - } - - for _, tc := range testCases { - t.Run(fmt.Sprintf("%s should error %t", tc.s, tc.r), func(t *testing.T) { - v, err := New(tc.s) - if (err != nil) != tc.r || v.Major != tc.a || v.Minor != tc.b || v.Patch != tc.c || v.Suffix != tc.d { - t.Fail() - } - }) - } -} - -func TestStringer(t *testing.T) { - testCases := []struct { - a, b, c int - d, want string - }{ - {1, 2, 3, "", "1.2.3"}, - {1, 2, 3, "h4", "1.2.3-h4"}, - {12, 34, 56, "h78", "12.34.56-h78"}, - } - - for _, tc := range testCases { - t.Run(tc.want, func(t *testing.T) { - v := Number{tc.a, tc.b, tc.c, tc.d} - if v.String() != tc.want { - t.Fail() - } - }) - } -} - -func TestGte(t *testing.T) { - testCases := []struct { - a, b, c int - r bool - }{ - {1, 1, 1, true}, - {1, 1, 2, true}, - {1, 1, 3, true}, - {1, 2, 1, true}, - {1, 2, 2, true}, - {1, 2, 3, true}, - {1, 3, 1, true}, - {1, 3, 2, true}, - {1, 3, 3, true}, - {2, 1, 1, true}, - {2, 1, 2, true}, - {2, 1, 3, true}, - {2, 2, 1, true}, - {2, 2, 2, true}, - {2, 2, 3, false}, - {2, 3, 1, false}, - {2, 3, 2, false}, - {2, 3, 3, false}, - {3, 1, 1, false}, - {3, 1, 2, false}, - {3, 1, 3, false}, - {3, 2, 1, false}, - {3, 2, 2, false}, - {3, 2, 3, false}, - {3, 3, 1, false}, - {3, 3, 2, false}, - {3, 3, 3, false}, - } - v1 := Number{2, 2, 2, ""} - - for _, tc := range testCases { - t.Run(fmt.Sprintf("%s >= %d.%d.%d == %t", v1, tc.a, tc.b, tc.c, tc.r), func(t *testing.T) { - r := v1.Gte(Number{tc.a, tc.b, tc.c, ""}) - if r != tc.r { - t.Fail() - } - }) - } -} - -func BenchmarkGteMajor(b *testing.B) { - v1 := Number{5, 5, 5, ""} - v2 := Number{6, 5, 5, ""} - - for i := 0; i < b.N; i++ { - _ = v1.Gte(v2) - } -} - -func BenchmarkGtePatch(b *testing.B) { - v1 := Number{5, 5, 5, ""} - v2 := Number{5, 5, 6, ""} - - for i := 0; i < b.N; i++ { - _ = v1.Gte(v2) - } -} - -func BenchmarkNew(b *testing.B) { - s := "7.1.12-h4" - - for i := 0; i < b.N; i++ { - _, _ = New(s) - } -} diff --git a/cmd/mktp/config.yaml b/cmd/mktp/config.yaml index 95ff5e40..ff60b01c 100644 --- a/cmd/mktp/config.yaml +++ b/cmd/mktp/config.yaml @@ -2,21 +2,21 @@ output: go_sdk: "../generated/pango" terraform_provider: "../generated/terraform-provider-panos" assets: - util_package: - source: "assets/util" - target: - go_sdk: true - terraform_provider: false - destination: "util" - errors_package: - source: "assets/errors" - target: - go_sdk: true - terraform_provider: false - destination: "errors" - version_package: - source: "assets/version" - target: - go_sdk: true - terraform_provider: false - destination: "version" +# util_package: +# source: "assets/util" +# target: +# go_sdk: true +# terraform_provider: false +# destination: "util" +# errors_package: +# source: "assets/errors" +# target: +# go_sdk: true +# terraform_provider: false +# destination: "errors" +# version_package: +# source: "assets/version" +# target: +# go_sdk: true +# terraform_provider: false +# destination: "version"