Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(client): Fix logic on config locks + change funcs name for more obvious #113

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 32 additions & 43 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,19 @@ import (
//
// The bit-wise flags are as follows:
//
// * LogQuiet: disables all logging
// * LogAction: action being performed (Set / Edit / Delete functions)
// * LogQuery: queries being run (Get / Show functions)
// * LogOp: operation commands (Op functions)
// * LogUid: User-Id commands (Uid functions)
// * LogLog: log retrieval commands
// * LogExport: log export commands
// * LogXpath: the resultant xpath
// * LogSend: xml docuemnt being sent
// * LogReceive: xml responses being received
// * LogOsxCurl: output an OSX cURL command for the data being sent in
// * LogCurlWithPersonalData: If doing a curl style logging, then include
// personal data in the curl command instead of tokens.
// - LogQuiet: disables all logging
// - LogAction: action being performed (Set / Edit / Delete functions)
// - LogQuery: queries being run (Get / Show functions)
// - LogOp: operation commands (Op functions)
// - LogUid: User-Id commands (Uid functions)
// - LogLog: log retrieval commands
// - LogExport: log export commands
// - LogXpath: the resultant xpath
// - LogSend: xml docuemnt being sent
// - LogReceive: xml responses being received
// - LogOsxCurl: output an OSX cURL command for the data being sent in
// - LogCurlWithPersonalData: If doing a curl style logging, then include
// personal data in the curl command instead of tokens.
const (
LogQuiet = 1 << (iota + 1)
LogAction
Expand Down Expand Up @@ -168,10 +168,10 @@ func (c *Client) Plugins() []plugin.Info {
// client's SystemInfo map.
//
// If not specified, the following is assumed:
// * Protocol: https
// * Port: (unspecified)
// * Timeout: 10
// * Logging: LogAction | LogUid
// - Protocol: https
// - Port: (unspecified)
// - Timeout: 10
// - Logging: LogAction | LogUid
func (c *Client) Initialize() error {
if len(c.rb) == 0 {
var e error
Expand Down Expand Up @@ -318,34 +318,23 @@ func (c *Client) RequestPasswordHash(val string) (string, error) {

// ValidateConfig performs a commit config validation check.
//
// Setting sync to true means that this function will block until the job
// finishes.
//
//
// The sleep param is an optional sleep duration to wait between polling for
// job completion. This param is only used if sync is set to true.
// # Cmd interface contained a formatted XML string struct which can be used to either marshalled into XML or one of the
// validate function.
//
// This function returns the job ID and if any errors were encountered.
func (c *Client) ValidateConfig(sync bool, sleep time.Duration) (uint, error) {
func (c *Client) ValidateConfig(cmd interface{}) (uint, []byte, error) {
var err error
data := url.Values{}
data.Set("type", "op")

c.LogOp("(op) validating config")
type op_req struct {
XMLName xml.Name `xml:"validate"`
Cmd string `xml:"full"`
}
job_ans := util.JobResponse{}
_, err = c.Op(op_req{}, "", nil, &job_ans)
if err != nil {
return 0, err
if err = addToData("cmd", cmd, true, &data); err != nil {
return 0, nil, err
}

id := job_ans.Id
if !sync {
return id, nil
}
ans := util.JobResponse{}

return id, c.WaitForJob(id, sleep, nil, nil)
b, _, err := c.Communicate(data, &ans)
return ans.Id, b, err
}

// RevertToRunningConfig discards any changes made and reverts to the last
Expand All @@ -356,10 +345,10 @@ func (c *Client) RevertToRunningConfig() error {
return err
}

// ConfigLocks returns any config locks that are currently in place.
// ShowConfigLocks returns any config locks that are currently in place.
//
// If vsys is an empty string, then the vsys will default to "shared".
func (c *Client) ConfigLocks(vsys string) ([]util.Lock, error) {
func (c *Client) ShowConfigLocks(vsys string) ([]util.Lock, error) {
var err error
var cmd string
ans := configLocks{}
Expand All @@ -368,7 +357,7 @@ func (c *Client) ConfigLocks(vsys string) ([]util.Lock, error) {
vsys = "shared"
}

if c.Version.Gte(version.Number{9, 1, 0, ""}) {
if !c.Version.Gte(version.Number{Major: 9, Minor: 1}) {
var tgt string
if vsys == "shared" {
tgt = "all"
Expand Down Expand Up @@ -427,10 +416,10 @@ func (c *Client) UnlockConfig(vsys string) error {
return err
}

// CommitLocks returns any commit locks that are currently in place.
// ShowCommitLocks returns any commit locks that are currently in place.
//
// If vsys is an empty string, then the vsys will default to "shared".
func (c *Client) CommitLocks(vsys string) ([]util.Lock, error) {
func (c *Client) ShowCommitLocks(vsys string) ([]util.Lock, error) {
if vsys == "" {
vsys = "shared"
}
Expand Down
30 changes: 23 additions & 7 deletions commit/pano.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package commit

import (
"encoding/xml"

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

Expand Down Expand Up @@ -116,6 +115,8 @@ type PanoramaCommitAll struct {
Description string
IncludeTemplate bool
ForceTemplateValues bool
ValidateOnly bool
Admins []string
Devices []string
}

Expand All @@ -139,26 +140,38 @@ func (o PanoramaCommitAll) Element() interface{} {
Description: o.Description,
IncludeTemplate: util.YesNo(o.IncludeTemplate),
ForceTemplateValues: util.YesNo(o.ForceTemplateValues),
ValidateOnly: util.YesNo(o.ValidateOnly),
},
}
if len(o.Admins) > 0 {
ans.DeviceGroup.Admins = util.StrToMem(o.Admins)
}
case TypeTemplate:
ans = panoCommitAll{
Template: &pcaTemplate{
Name: o.Name,
Description: o.Description,
ForceTemplateValues: util.YesNo(o.ForceTemplateValues),
Devices: util.StrToMem(o.Devices),
ValidateOnly: util.YesNo(o.ValidateOnly),
},
}
if len(o.Admins) > 0 {
ans.Template.Admins = util.StrToMem(o.Admins)
}
case TypeTemplateStack:
ans = panoCommitAll{
TemplateStack: &pcaTemplate{
Name: o.Name,
Description: o.Description,
ForceTemplateValues: util.YesNo(o.ForceTemplateValues),
Devices: util.StrToMem(o.Devices),
ValidateOnly: util.YesNo(o.ValidateOnly),
},
}
if len(o.Admins) > 0 {
ans.TemplateStack.Admins = util.StrToMem(o.Admins)
}
case TypeLogCollectorGroup:
ans = panoCommitAll{
LogCollectorGroup: &pcaLogCollectorGroup{
Expand All @@ -181,7 +194,6 @@ func (o PanoramaCommitAll) Element() interface{} {
},
}
}

return ans
}

Expand All @@ -195,10 +207,12 @@ type panoCommitAll struct {
}

type pcaDeviceGroup struct {
DgInfo pcaDgInfo `xml:"device-group"`
Description string `xml:"description,omitempty"`
IncludeTemplate string `xml:"include-template"`
ForceTemplateValues string `xml:"force-template-values"`
DgInfo pcaDgInfo `xml:"device-group"`
Admins *util.MemberType `xml:"admin,omitempty"`
Description string `xml:"description,omitempty"`
IncludeTemplate string `xml:"include-template"`
ForceTemplateValues string `xml:"force-template-values"`
ValidateOnly string `xml:"validate-only"`
}

type pcaDgInfo struct {
Expand All @@ -211,10 +225,12 @@ type pcaDgInfoEntry struct {
}

type pcaTemplate struct {
Admins *util.MemberType `xml:"admin,omitempty"`
Devices *util.MemberType `xml:"device"`
Name string `xml:"name"`
Description string `xml:"description,omitempty"`
Devices *util.MemberType `xml:"device"`
ForceTemplateValues string `xml:"force-template-values"`
ValidateOnly string `xml:"validate-only"`
}

type pcaLogCollectorGroup struct {
Expand Down
7 changes: 5 additions & 2 deletions commit/pano_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ func TestPanoCommitAllDeviceGroup(t *testing.T) {
"<description>device group</description>",
"<include-template>yes</include-template>",
"<force-template-values>no</force-template-values>",
"<validate-only>no</validate-only>",
"</shared-policy>",
"</commit-all>",
}
Expand All @@ -142,10 +143,11 @@ func TestPanoCommitAllTemplate(t *testing.T) {
s := []string{
"<commit-all>",
"<template>",
"<device><member>12321</member></device>",
"<name>tmpl1</name>",
"<description>template</description>",
"<device><member>12321</member></device>",
"<force-template-values>yes</force-template-values>",
"<validate-only>no</validate-only>",
"</template>",
"</commit-all>",
}
Expand All @@ -169,10 +171,11 @@ func TestPanoCommitAllTemplateStack(t *testing.T) {
s := []string{
"<commit-all>",
"<template-stack>",
"<device><member>12321</member></device>",
"<name>ts1</name>",
"<description>template stack</description>",
"<device><member>12321</member></device>",
"<force-template-values>yes</force-template-values>",
"<validate-only>no</validate-only>",
"</template-stack>",
"</commit-all>",
}
Expand Down
81 changes: 81 additions & 0 deletions commit/validate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package commit

import (
"encoding/xml"
"github.com/PaloAltoNetworks/pango/util"
)

// PanoramaValidate is a Panorama Valid structure contained all option for Client.ValidateConfig().
type PanoramaValidate struct {
Admins []string
DeviceGroups []string
LogCollectors []string
LogCollectorGroups []string
Templates []string
TemplateStacks []string
WildfireAppliances []string
WildfireApplianceClusters []string
ExcludeDeviceAndNetwork bool
ExcludeSharedObjects bool
Full bool
}

// PanoramaValidateAll it is a shell struct for doing validate all changes in Panorama.
type PanoramaValidateAll struct{}

// Element this function return an interface ready to be marshalled into XML for validate.
func (o PanoramaValidate) Element() interface{} {
ans := panoValidate{}

var p *panoValidatePartial
if len(o.Admins) > 0 || len(o.DeviceGroups) > 0 || len(o.Templates) > 0 ||
len(o.TemplateStacks) > 0 || len(o.LogCollectors) > 0 || len(o.LogCollectorGroups) > 0 {
p = &panoValidatePartial{
Admins: util.StrToMem(o.Admins),
DeviceGroups: util.StrToMem(o.DeviceGroups),
Templates: util.StrToMem(o.Templates),
TemplateStacks: util.StrToMem(o.TemplateStacks),
WildfireAppliances: util.StrToMem(o.WildfireAppliances),
WildfireClusters: util.StrToMem(o.WildfireApplianceClusters),
LogCollectors: util.StrToMem(o.LogCollectors),
LogCollectorGroups: util.StrToMem(o.LogCollectorGroups),
}

if o.ExcludeSharedObjects {
p.ExcludeSharedObjects = "excluded"
}

if o.ExcludeDeviceAndNetwork {
p.ExcludeDeviceAndNetwork = "excluded"
}
} else {
ans.Full = &panoValidateFull{}
}

ans.Partial = p

return ans
}

// panoValidate main XML structure for validate, it contains main 'validate' option and regarded for the action
// it can be either 'full' or 'partial'
type panoValidate struct {
XMLName xml.Name `xml:"validate"`
Full *panoValidateFull `xml:"full"`
Partial *panoValidatePartial `xml:"partial"`
}

type panoValidateFull struct{}

type panoValidatePartial struct {
Admins *util.MemberType `xml:"admin"`
DeviceGroups *util.MemberType `xml:"device-group"`
Templates *util.MemberType `xml:"template"`
TemplateStacks *util.MemberType `xml:"template-stack"`
WildfireAppliances *util.MemberType `xml:"wildfire-appliance"`
WildfireClusters *util.MemberType `xml:"wildfire-appliance-cluster"`
LogCollectors *util.MemberType `xml:"log-collector"`
LogCollectorGroups *util.MemberType `xml:"log-collector-group"`
ExcludeDeviceAndNetwork string `xml:"device-and-network,omitempty"`
ExcludeSharedObjects string `xml:"shared-object,omitempty"`
}
Loading