├── .github └── workflows │ └── sanity-check.yml ├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── SUPPORT.md ├── alert ├── const.go ├── funcs.go ├── rule │ ├── const.go │ ├── funcs.go │ └── structs.go └── structs.go ├── anomalySettings ├── anomalyTrustedList │ ├── const.go │ ├── funcs.go │ └── structs.go ├── const.go ├── funcs.go └── structs.go ├── client.go ├── client_test.go ├── cloud ├── account-v2 │ ├── azureTemplate │ │ ├── const.go │ │ ├── funcs.go │ │ └── structs.go │ ├── const.go │ ├── externalid │ │ ├── const.go │ │ ├── funcs.go │ │ └── structs.go │ ├── funcs.go │ ├── gcpTemplate │ │ ├── const.go │ │ ├── funcs.go │ │ └── structs.go │ ├── ibmTemplate │ │ ├── const.go │ │ ├── funcs.go │ │ └── structs.go │ ├── org │ │ ├── const.go │ │ ├── funcs.go │ │ └── structs.go │ ├── structs.go │ └── supportedFeatures │ │ ├── const.go │ │ ├── funcs.go │ │ └── structs.go └── account │ ├── const.go │ ├── funcs.go │ ├── group │ ├── const.go │ ├── funcs.go │ └── structs.go │ ├── org │ ├── const.go │ ├── funcs.go │ └── structs.go │ └── structs.go ├── collection ├── const.go ├── funcs.go └── structs.go ├── compliance └── standard │ ├── const.go │ ├── funcs.go │ ├── requirement │ ├── const.go │ ├── funcs.go │ ├── section │ │ ├── const.go │ │ ├── funcs.go │ │ └── structs.go │ └── structs.go │ └── structs.go ├── const.go ├── data-security ├── datapattern │ ├── const.go │ ├── funcs.go │ └── structs.go └── dataprofile │ ├── const.go │ ├── funcs.go │ └── structs.go ├── doc.go ├── error.go ├── funcs.go ├── go.mod ├── integration ├── const.go ├── funcs.go └── structs.go ├── interface.go ├── ip-address ├── const.go ├── funcs.go └── structs.go ├── notification-template ├── const.go ├── funcs.go └── structs.go ├── permission_group ├── const.go ├── funcs.go └── structs.go ├── policy ├── const.go ├── funcs.go └── structs.go ├── report ├── const.go ├── funcs.go └── structs.go ├── resource-list ├── const.go ├── funcs.go └── structs.go ├── rql ├── history │ ├── const.go │ ├── funcs.go │ └── structs.go └── search │ ├── const.go │ ├── funcs.go │ └── structs.go ├── settings └── enterprise │ ├── const.go │ ├── funcs.go │ └── structs.go ├── structs.go ├── timerange ├── const.go └── struct.go ├── trusted-alert-ip ├── const.go ├── funcs.go └── structs.go └── user ├── profile ├── const.go ├── funcs.go └── structs.go └── role ├── const.go ├── funcs.go └── structs.go /.github/workflows/sanity-check.yml: -------------------------------------------------------------------------------- 1 | name: Sanity Check 2 | on: [push, pull_request] 3 | 4 | jobs: 5 | build: 6 | name: Build 7 | runs-on: ubuntu-latest 8 | steps: 9 | 10 | - name: Set up Go 1.13 11 | uses: actions/setup-go@0caeaed6fd66a828038c2da3c0f662a42862658f # v1 12 | with: 13 | go-version: 1.13 14 | id: go 15 | 16 | - name: Check out code into the Go module directory 17 | uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2 18 | 19 | - name: Get dependencies 20 | run: | 21 | go get -v -t -d ./... 22 | if [ -f Gopkg.toml ]; then 23 | curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh 24 | dep ensure 25 | fi 26 | 27 | - name: Run unittests 28 | run: go test ./... 29 | 30 | - name: Build 31 | run: go build -v . 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # Dependency directories (remove the comment below to include it) 15 | # vendor/ 16 | 17 | # Ignore vim swap files 18 | *.swp 19 | 20 | #IntelliJ Files 21 | .idea -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | default: test 2 | 3 | test: 4 | go test ./... 5 | 6 | verbose: 7 | go test -v ./... 8 | 9 | fmt: 10 | find . -type f -name \*.go | xargs gofmt -w 11 | 12 | .PHONY: test verbose fmt 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | prisma-cloud-go 2 | =============== 3 | 4 | [![GoDoc](https://godoc.org/github.com/paloaltonetworks/prisma-cloud-go?status.svg)](https://godoc.org/github.com/paloaltonetworks/prisma-cloud-go) 5 | [![Build](https://github.com/paloaltonetworks/prisma-cloud-go/workflows/Sanity%20Check/badge.svg?branch=master)](https://github.com/paloaltonetworks/prisma-cloud-go/actions?query=workflow%3A%22Sanity+Check%22) 6 | 7 | Prisma Cloud SDK in Go 8 | -------------------------------------------------------------------------------- /SUPPORT.md: -------------------------------------------------------------------------------- 1 | Palo Alto Networks Supported 2 | 3 | The software and templates in this repo are released under the official support 4 | policy of Palo Alto Networks through the support options that you've purchased, 5 | for example Premium Support, support teams, or ASC (Authorized Support Centers) 6 | partners and Premium Partner Support options. The support scope is restricted to 7 | troubleshooting for the stated/intended use cases and product versions specified 8 | in the project documentation and does not cover customization of the scripts or 9 | templates. 10 | -------------------------------------------------------------------------------- /alert/const.go: -------------------------------------------------------------------------------- 1 | package alert 2 | 3 | const ( 4 | singular = "alert" 5 | plural = "alerts" 6 | ) 7 | -------------------------------------------------------------------------------- /alert/funcs.go: -------------------------------------------------------------------------------- 1 | package alert 2 | 3 | import ( 4 | pc "github.com/paloaltonetworks/prisma-cloud-go" 5 | ) 6 | 7 | // List returns a list of alerts that match the constraints specified. 8 | func List(c pc.PrismaCloudClient, req Request) (Response, error) { 9 | c.Log(pc.LogAction, "(get) list of %s", plural) 10 | 11 | var resp Response 12 | 13 | // Sanity check the time range. 14 | if err := req.TimeRange.SetType(); err != nil { 15 | return resp, err 16 | } 17 | 18 | _, err := c.Communicate("POST", []string{"v2", "alert"}, nil, req, &resp) 19 | return resp, err 20 | } 21 | 22 | // Get returns information about an alert for the specified ID. 23 | func Get(c pc.PrismaCloudClient, id string) (Alert, error) { 24 | c.Log(pc.LogAction, "(get) %s: %s", singular, id) 25 | 26 | var ans Alert 27 | 28 | _, err := c.Communicate("GET", []string{"alert", id}, nil, nil, &ans) 29 | return ans, err 30 | } 31 | -------------------------------------------------------------------------------- /alert/rule/const.go: -------------------------------------------------------------------------------- 1 | package rule 2 | 3 | var Suffix = []string{"alert", "rule"} 4 | 5 | // Valid values for NotificationConfig.Frequency. 6 | const ( 7 | FrequencyAsItHappens = "as_it_happens" 8 | FrequencyDaily = "daily" 9 | FrequencyWeekly = "weekly" 10 | FrequencyMonthly = "monthly" 11 | ) 12 | 13 | // valid values for NotificationConfig.Type. 14 | const ( 15 | TypeEmail = "email" 16 | TypeSlack = "slack" 17 | TypeSplunk = "splunk" 18 | TypeAmazonSqs = "amazon_sqs" 19 | TypeMicrosoftTeams = "microsoft_teams" 20 | TypeWebhook = "webhook" 21 | TypeAwsSecurityHub = "aws_security_hub" 22 | TypeGoogleCscc = "google_cscc" 23 | TypeServiceNow = "service_now" 24 | TypePagerDuty = "pager_duty" 25 | TypeDemisto = "demisto" 26 | TypeAzureServiceBusQueue = "azure_service_bus_queue" 27 | TypeSnowFlake = "snowflake" 28 | TypeAwsS3 = "aws_s3" 29 | TypeJira = "jira" 30 | ) 31 | 32 | const ( 33 | singular = "alert rule" 34 | plural = "alert rules" 35 | ) 36 | -------------------------------------------------------------------------------- /alert/rule/funcs.go: -------------------------------------------------------------------------------- 1 | package rule 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | pc "github.com/paloaltonetworks/prisma-cloud-go" 8 | ) 9 | 10 | // Identify returns the ID associated with the specified alert rule name. 11 | func Identify(c pc.PrismaCloudClient, name string) (string, error) { 12 | c.Log(pc.LogAction, "(get) id for %s: %s", singular, name) 13 | 14 | list, err := List(c) 15 | if err != nil { 16 | return "", err 17 | } 18 | 19 | for _, o := range list { 20 | if o.Name == name { 21 | return o.PolicyScanConfigId, nil 22 | } 23 | } 24 | 25 | return "", pc.ObjectNotFoundError 26 | } 27 | 28 | // List returns a list of alerts that match the constraints specified. 29 | func List(c pc.PrismaCloudClient) ([]Rule, error) { 30 | c.Log(pc.LogAction, "(get) list of %s", plural) 31 | 32 | var ans []Rule 33 | 34 | _, err := c.Communicate("GET", []string{"v2", "alert", "rule"}, nil, nil, &ans) 35 | return ans, err 36 | } 37 | 38 | // Get returns information about an alert for the specified ID. 39 | func Get(c pc.PrismaCloudClient, id string) (Rule, error) { 40 | c.Log(pc.LogAction, "(get) %s: %s", singular, id) 41 | 42 | var ans Rule 43 | 44 | path := make([]string, 0, len(Suffix)+1) 45 | path = append(path, Suffix...) 46 | path = append(path, id) 47 | 48 | _, err := c.Communicate("GET", path, nil, nil, &ans) 49 | return ans, err 50 | } 51 | 52 | // Create makes a new alert rule. 53 | func Create(c pc.PrismaCloudClient, rule Rule) error { 54 | return createUpdate(false, c, rule) 55 | } 56 | 57 | // Update modifies information about the alert rule that has the specified ID. 58 | func Update(c pc.PrismaCloudClient, rule Rule) error { 59 | return createUpdate(true, c, rule) 60 | } 61 | 62 | // Delete removes the alert rule that has the specified ID. 63 | func Delete(c pc.PrismaCloudClient, id string, rule Rule) error { 64 | c.Log(pc.LogAction, "(delete) %s id:%s", singular, id) 65 | path := make([]string, 0, len(Suffix)+1) 66 | path = append(path, Suffix...) 67 | path = append(path, id) 68 | _, err := c.Communicate("GET", path, nil, nil, nil) 69 | 70 | if err != nil { 71 | _, err := c.Communicate("DELETE", path, nil, nil, nil) 72 | return err 73 | } else if rule.Deleted == false { 74 | _, err := c.Communicate("DELETE", path, nil, nil, nil) 75 | return err 76 | } 77 | 78 | return err 79 | } 80 | 81 | func createUpdate(exists bool, c pc.PrismaCloudClient, rule Rule) error { 82 | var ( 83 | logMsg strings.Builder 84 | method string 85 | ) 86 | 87 | logMsg.Grow(30) 88 | logMsg.WriteString("(") 89 | if exists { 90 | logMsg.WriteString("update") 91 | method = "PUT" 92 | } else { 93 | logMsg.WriteString("create") 94 | method = "POST" 95 | } 96 | logMsg.WriteString(") ") 97 | 98 | logMsg.WriteString(" ") 99 | logMsg.WriteString(singular) 100 | if exists { 101 | fmt.Fprintf(&logMsg, ": %s", rule.PolicyScanConfigId) 102 | } 103 | 104 | c.Log(pc.LogAction, logMsg.String()) 105 | 106 | path := make([]string, 0, len(Suffix)+1) 107 | path = append(path, Suffix...) 108 | if exists { 109 | path = append(path, rule.PolicyScanConfigId) 110 | } 111 | 112 | _, err := c.Communicate(method, path, nil, rule, nil) 113 | return err 114 | } 115 | -------------------------------------------------------------------------------- /alert/rule/structs.go: -------------------------------------------------------------------------------- 1 | package rule 2 | 3 | type Rule struct { 4 | PolicyScanConfigId string `json:"policyScanConfigId,omitempty"` 5 | Name string `json:"name"` 6 | Description string `json:"description"` 7 | Enabled bool `json:"enabled"` 8 | ScanAll bool `json:"scanAll"` 9 | Policies []string `json:"policies,omitempty"` 10 | PolicyLabels []string `json:"policyLabels"` 11 | ExcludedPolicies []string `json:"excludedPolicies"` 12 | Target Target `json:"target"` 13 | LastModifiedOn int `json:"lastModifiedOn,omitempty"` 14 | LastModifiedBy string `json:"lastModifiedBy,omitempty"` 15 | NotificationConfig []NotificationConfig `json:"alertRuleNotificationConfig,omitempty"` 16 | AllowAutoRemediate bool `json:"allowAutoRemediate"` 17 | DelayNotificationMs int `json:"delayNotificationMs"` 18 | NotifyOnOpen bool `json:"notifyOnOpen"` 19 | NotifyOnSnoozed bool `json:"notifyOnSnoozed,omitempty"` 20 | NotifyOnDismissed bool `json:"notifyOnDismissed,omitempty"` 21 | NotifyOnResolved bool `json:"notifyOnResolved,omitempty"` 22 | Owner string `json:"owner,omitempty"` 23 | NotificationChannels []string `json:"notificationChannels,omitempty"` 24 | OpenAlertsCount int `json:"openAlertsCount,omitempty"` 25 | ReadOnly bool `json:"readOnly,omitempty"` 26 | Deleted bool `json:"deleted,omitempty"` 27 | } 28 | 29 | type Target struct { 30 | AccountGroups []string `json:"accountGroups"` 31 | ExcludedAccounts []string `json:"excludedAccounts,omitempty"` 32 | Regions []string `json:"regions,omitempty"` 33 | Tags []Tag `json:"tags,omitempty"` 34 | ResourceList ResourceList `json:"includedResourceLists,omitempty"` 35 | AlertRulePolicyFilter AlertRulePolicyFilter `json:"alertRulePolicyFilter,omitempty"` 36 | } 37 | 38 | type Tag struct { 39 | Key string `json:"key"` 40 | Values []string `json:"values"` 41 | } 42 | 43 | type ResourceList struct { 44 | IncludedResourceLists []string `json:"computeAccessGroupIds,omitempty"` 45 | } 46 | 47 | type AlertRulePolicyFilter struct { 48 | CloudType []string `json:"cloud.type,omitempty"` 49 | PolicyComplianceStandard []string `json:"policy.complianceStandard,omitempty"` 50 | PolicyLabel []string `json:"policy.label,omitempty"` 51 | PolicySeverity []string `json:"policy.severity,omitempty"` 52 | } 53 | 54 | type NotificationConfig struct { 55 | Id string `json:"id,omitempty"` 56 | Frequency string `json:"frequency,omitempty"` 57 | Enabled bool `json:"enabled"` 58 | Recipients []string `json:"recipients"` 59 | DetailedReport bool `json:"detailedReport"` 60 | WithCompression bool `json:"withCompression"` 61 | IncludeRemediation bool `json:"includeRemediation"` 62 | LastUpdated int `json:"lastUpdated"` 63 | LastSentTs int `json:"last_send_ts"` 64 | Type string `json:"type"` 65 | TemplateId string `json:"templateId,omitempty"` 66 | TimezoneId string `json:"timezone,omitempty"` 67 | DayOfMonth int `json:"dayOfMonth,omitempty"` 68 | RruleSchedule string `json:"rruleSchedule,omitempty"` 69 | FrequencyFromRrule string `json:"frequencyFromRRule,omitempty"` 70 | HourOfDay int `json:"hourOfDay,omitempty"` 71 | DaysOfWeek []Day `json:"daysOfWeek,omitempty"` 72 | } 73 | 74 | type Day struct { 75 | Day string `json:"day"` 76 | Offset int `json:"offset"` 77 | } 78 | -------------------------------------------------------------------------------- /alert/structs.go: -------------------------------------------------------------------------------- 1 | package alert 2 | 3 | import ( 4 | "github.com/paloaltonetworks/prisma-cloud-go/timerange" 5 | ) 6 | 7 | type Request struct { 8 | TimeRange timerange.TimeRange `json:"timeRange"` 9 | Limit int `json:"limit,omitempty"` 10 | Offset int `json:"offset,omitempty"` 11 | Detailed bool `json:"detailed"` 12 | PageToken string `json:"pageToken,omitempty"` 13 | SortBy []string `json:"sortBy,omitempty"` 14 | Filters []Filter `json:"filters,omitempty"` 15 | } 16 | 17 | type Filter struct { 18 | Name string `json:"name"` 19 | Operator string `json:"operator"` 20 | Value string `json:"value"` 21 | } 22 | 23 | type Response struct { 24 | Total int `json:"totalRows"` 25 | Data []Alert `json:"items"` 26 | PageToken string `json:"nextPageToken"` 27 | } 28 | 29 | type Alert struct { 30 | Id string `json:"id"` 31 | Status string `json:"status"` 32 | FirstSeen int `json:"firstSeen"` 33 | LastSeen int `json:"lastSeen"` 34 | AlertTime int `json:"alertTime"` 35 | EventOccurred int `json:"eventOccurred"` 36 | TriggeredBy string `json:"triggeredBy"` 37 | AlertCount int `json:"alertCount"` 38 | History []History `json:"history"` 39 | Policy Policy `json:"policy"` 40 | Risk RiskDetail `json:"riskDetail"` 41 | Resource Resource `json:"resource"` 42 | InvestigateOptions InvestigateOptions `json:"investigateOptions"` 43 | } 44 | 45 | type History struct { 46 | Reason string `json:"reason"` 47 | Status string `json:"status"` 48 | ModifiedBy string `json:"modifiedBy"` 49 | ModifiedOn int `json:"modifiedOn"` 50 | } 51 | 52 | type Policy struct { 53 | Id string `json:"policyId"` 54 | Type string `json:"policyType"` 55 | SystemDefault bool `json:"systemDefault"` 56 | Remediable bool `json:"remediable"` 57 | } 58 | 59 | type RiskDetail struct { 60 | RiskScore RiskScore `json:"riskScore"` 61 | Rating string `json:"rating"` 62 | Score string `json:"score"` 63 | } 64 | 65 | type RiskScore struct { 66 | Score int `json:"score"` 67 | MaxScore int `json:"maxScore"` 68 | } 69 | 70 | type Resource struct { 71 | Rrn string `json:"rrn"` 72 | Id string `json:"id"` 73 | Name string `json:"name"` 74 | Account string `json:"account"` 75 | AccountId string `json:"accountId"` 76 | CloudAccountGroups []string `json:"cloudAccountGroups"` 77 | Region string `json:"region"` 78 | RegionId string `json:"regionId"` 79 | ResourceType string `json:"resourceType"` 80 | ResourceApiName string `json:"resourceApiName"` 81 | Url string `json:"url"` 82 | Data interface{} `json:"data"` 83 | Tags interface{} `json:"resourceTags,omitempty"` 84 | AlertAttribution interface{} `json:"alertAttribution"` 85 | CloudType string `json:"cloudType"` 86 | } 87 | 88 | type InvestigateOptions struct { 89 | SearchId string `json:"searchId"` 90 | StartTs int `json:"startTs"` 91 | EndTs int `json:"endTs"` 92 | } 93 | -------------------------------------------------------------------------------- /anomalySettings/anomalyTrustedList/const.go: -------------------------------------------------------------------------------- 1 | package anomalyTrustedList 2 | 3 | const ( 4 | singular = "Anomaly trusted list" 5 | plural = "Anomaly trusted lists" 6 | ) 7 | 8 | var Suffix = []string{"anomalies/trusted_list"} 9 | -------------------------------------------------------------------------------- /anomalySettings/anomalyTrustedList/funcs.go: -------------------------------------------------------------------------------- 1 | package anomalyTrustedList 2 | 3 | import ( 4 | "fmt" 5 | pc "github.com/paloaltonetworks/prisma-cloud-go" 6 | "strconv" 7 | "strings" 8 | ) 9 | 10 | // List returns a list of all entries in the anomaly trusted list. 11 | func List(c pc.PrismaCloudClient) ([]AnomalyTrustedList, error) { 12 | c.Log(pc.LogAction, "(get) list of %s", plural) 13 | 14 | var ans []AnomalyTrustedList 15 | 16 | _, err := c.Communicate("GET", Suffix, nil, nil, &ans) 17 | return ans, err 18 | } 19 | 20 | // Identify returns the ID for the given anomaly trusted list. 21 | func Identify(c pc.PrismaCloudClient, id string) (string, error) { 22 | c.Log(pc.LogAction, "(get) id for %s id:%s", singular, id) 23 | 24 | list, err := List(c) 25 | if err != nil { 26 | return "", err 27 | } 28 | 29 | for _, o := range list { 30 | if strconv.Itoa(o.Atl_Id) == id { 31 | return id, nil 32 | } 33 | } 34 | 35 | return "", pc.ObjectNotFoundError 36 | } 37 | 38 | // Get returns anomaly trusted list for the specified ID 39 | func Get(c pc.PrismaCloudClient, id string) (AnomalyTrustedList, error) { 40 | c.Log(pc.LogAction, "(get) %s id:%s", singular, id) 41 | var ans AnomalyTrustedList 42 | path := make([]string, 0, len(Suffix)+1) 43 | path = append(path, Suffix...) 44 | path = append(path, id) 45 | _, err := c.Communicate("GET", path, nil, nil, &ans) 46 | return ans, err 47 | } 48 | 49 | // Create creates a new anomaly trusted list. 50 | func Create(c pc.PrismaCloudClient, anomalyTrustedList AnomalyTrustedList) (int, error) { 51 | return createUpdate(false, c, anomalyTrustedList) 52 | } 53 | 54 | // Update modifies information related to an anomaly trusted list 55 | func Update(c pc.PrismaCloudClient, anomalyTrustedList AnomalyTrustedList) (int, error) { 56 | return createUpdate(true, c, anomalyTrustedList) 57 | } 58 | 59 | // Delete removes an anomaly trusted list using its ID. 60 | func Delete(c pc.PrismaCloudClient, id string) error { 61 | c.Log(pc.LogAction, "(delete) %s id:%s", singular, id) 62 | 63 | path := make([]string, 0, len(Suffix)+1) 64 | path = append(path, Suffix...) 65 | path = append(path, id) 66 | _, err := c.Communicate("DELETE", path, nil, nil, nil) 67 | return err 68 | } 69 | 70 | func createUpdate(exists bool, c pc.PrismaCloudClient, anomalyTrustedList AnomalyTrustedList) (int, error) { 71 | var ( 72 | logMsg strings.Builder 73 | method string 74 | ) 75 | 76 | logMsg.Grow(30) 77 | logMsg.WriteString("(") 78 | if exists { 79 | logMsg.WriteString("update") 80 | method = "POST" 81 | } else { 82 | logMsg.WriteString("create") 83 | method = "POST" 84 | } 85 | logMsg.WriteString(") ") 86 | 87 | logMsg.WriteString(singular) 88 | 89 | id := strconv.Itoa(anomalyTrustedList.Atl_Id) 90 | if exists { 91 | fmt.Fprintf(&logMsg, ":%d", anomalyTrustedList.Atl_Id) 92 | } 93 | 94 | c.Log(pc.LogAction, logMsg.String()) 95 | 96 | path := make([]string, 0, len(Suffix)+1) 97 | path = append(path, Suffix...) 98 | if exists { 99 | path = append(path, id) 100 | } 101 | 102 | var ans [1]int //returns integer as response if succeeds 103 | _, err := c.Communicate(method, path, nil, anomalyTrustedList, &ans) 104 | return ans[0], err 105 | } 106 | -------------------------------------------------------------------------------- /anomalySettings/anomalyTrustedList/structs.go: -------------------------------------------------------------------------------- 1 | package anomalyTrustedList 2 | 3 | type AnomalyTrustedListRequest struct { 4 | Name string `json:"name"` 5 | Description string `json:"description"` 6 | ApplicablePolicies []string `json:"applicablePolicies"` 7 | TrustedListType string `json:"trustedListType"` 8 | AccountId string `json:"accountID"` 9 | VPC string `json:"vpc"` 10 | TrustedListEntries []TrustedListEntry `json:"trustedListEntries"` 11 | } 12 | 13 | type AnomalyTrustedList struct { 14 | Atl_Id int `json:"id"` 15 | Name string `json:"name"` 16 | Description string `json:"description"` 17 | ApplicablePolicies []string `json:"applicablePolicies"` 18 | TrustedListType string `json:"trustedListType"` 19 | AccountId string `json:"accountID"` 20 | VPC string `json:"vpc"` 21 | TrustedListEntries []TrustedListEntry `json:"trustedListEntries"` 22 | CreatedBy string `json:"createdBy"` 23 | CreatedOn int `json:"createdOn"` 24 | } 25 | 26 | type TrustedListEntry struct { 27 | ImageID string `json:"imageID"` 28 | IpCIDR string `json:"ipCIDR"` 29 | Port string `json:"port"` 30 | ResourceID string `json:"resourceID"` 31 | Service string `json:"service"` 32 | Subject string `json:"subject"` 33 | TagKey string `json:"tagKey"` 34 | TagValue string `json:"tagValue"` 35 | Domain string `json:"domain"` 36 | Protocol string `json:"protocol"` 37 | } 38 | -------------------------------------------------------------------------------- /anomalySettings/const.go: -------------------------------------------------------------------------------- 1 | package anomalySettings 2 | 3 | const ( 4 | singular = "anomalySetting" 5 | plural = "anomalySettings" 6 | ) 7 | 8 | var Suffix = []string{"anomalies/settings"} 9 | -------------------------------------------------------------------------------- /anomalySettings/funcs.go: -------------------------------------------------------------------------------- 1 | package anomalySettings 2 | 3 | import ( 4 | "fmt" 5 | "net/url" 6 | "strings" 7 | 8 | pc "github.com/paloaltonetworks/prisma-cloud-go" 9 | ) 10 | 11 | // List returns a list of available anomalySettings settings 12 | func List(c pc.PrismaCloudClient, t string) (map[string]interface{}, error) { 13 | c.Log(pc.LogAction, "(get) list of %s", plural) 14 | 15 | var ans map[string]interface{} 16 | var query url.Values 17 | if t != "" { 18 | query = url.Values{} 19 | query.Add("type", t) 20 | } 21 | if _, err := c.Communicate("GET", Suffix, query, nil, &ans); err != nil { 22 | return ans, err 23 | } 24 | 25 | return ans, nil 26 | } 27 | 28 | // Get returns anomaly settings for the specified policy ID 29 | func Get(c pc.PrismaCloudClient, id string) (AnomalySettings, error) { 30 | c.Log(pc.LogAction, "(get) %s id:%s", singular, id) 31 | 32 | var ans AnomalySettings 33 | path := make([]string, 0, len(Suffix)+1) 34 | path = append(path, Suffix...) 35 | path = append(path, id) 36 | 37 | _, err := c.Communicate("GET", path, nil, nil, &ans) 38 | return ans, err 39 | } 40 | 41 | // Create modifies the existing anomaly setting. 42 | func Create(c pc.PrismaCloudClient, anomalySettings AnomalySettings) error { 43 | return createUpdate(false, c, anomalySettings) 44 | } 45 | 46 | // Update modifies the existing anomaly setting. 47 | func Update(c pc.PrismaCloudClient, anomalySettings AnomalySettings) error { 48 | return createUpdate(false, c, anomalySettings) 49 | } 50 | 51 | func createUpdate(exists bool, c pc.PrismaCloudClient, anomalySettings AnomalySettings) error { 52 | var ( 53 | logMsg strings.Builder 54 | method string 55 | ) 56 | 57 | logMsg.Grow(30) 58 | logMsg.WriteString("(") 59 | if exists { 60 | logMsg.WriteString("update") 61 | method = "POST" 62 | } else { 63 | logMsg.WriteString("create") 64 | method = "POST" 65 | } 66 | logMsg.WriteString(") ") 67 | 68 | logMsg.WriteString(singular) 69 | if exists { 70 | fmt.Fprintf(&logMsg, ":%s", anomalySettings.PolicyId) 71 | } 72 | 73 | c.Log(pc.LogAction, logMsg.String()) 74 | 75 | path := make([]string, 0, len(Suffix)+1) 76 | path = append(path, Suffix...) 77 | path = append(path, anomalySettings.PolicyId) 78 | _, err := c.Communicate(method, path, nil, anomalySettings, nil) 79 | return err 80 | } 81 | -------------------------------------------------------------------------------- /anomalySettings/structs.go: -------------------------------------------------------------------------------- 1 | package anomalySettings 2 | 3 | type Response struct { 4 | AnomalySettingsResponse struct { 5 | AlertDisposition string `json:"alertDisposition"` 6 | AlertDispositionDescription AlertDispositionDescription `json:"alertDispositionDescription"` 7 | PolicyDescription string `json:"policyDescription"` 8 | PolicyName string `json:"policyName,omitempty"` 9 | TrainingModelDescription TrainingModelDescription `json:"trainingModelDescription"` 10 | TrainingModelThreshold string `json:"trainingModelThreshold"` 11 | } 12 | } 13 | 14 | type AnomalySettingsResponse struct { 15 | AlertDisposition string `json:"alertDisposition"` 16 | AlertDispositionDescription AlertDispositionDescription `json:"alertDispositionDescription"` 17 | PolicyDescription string `json:"policyDescription"` 18 | PolicyName string `json:"policyName,omitempty"` 19 | TrainingModelDescription TrainingModelDescription `json:"trainingModelDescription"` 20 | TrainingModelThreshold string `json:"trainingModelThreshold"` 21 | } 22 | 23 | type AnomalySettings struct { 24 | PolicyId string `json:"id"` 25 | AlertDisposition string `json:"alertDisposition"` 26 | AlertDispositionDescription AlertDispositionDescription `json:"alertDispositionDescription"` 27 | PolicyDescription string `json:"policyDescription"` 28 | PolicyName string `json:"policyName,omitempty"` 29 | TrainingModelDescription TrainingModelDescription `json:"trainingModelDescription"` 30 | TrainingModelThreshold string `json:"trainingModelThreshold"` 31 | Type string `json:"type"` 32 | } 33 | 34 | type AlertDispositionDescription struct { 35 | Aggressive string `json:"aggressive"` 36 | Moderate string `json:"moderate"` 37 | Conservative string `json:"conservative"` 38 | } 39 | 40 | type TrainingModelDescription struct { 41 | Low string `json:"low"` 42 | Medium string `json:"medium"` 43 | High string `json:"high"` 44 | } 45 | -------------------------------------------------------------------------------- /client.go: -------------------------------------------------------------------------------- 1 | package prismacloud 2 | 3 | import ( 4 | "bytes" 5 | "crypto/tls" 6 | "encoding/json" 7 | "fmt" 8 | "github.com/google/uuid" 9 | "io/ioutil" 10 | "log" 11 | "net/http" 12 | "net/url" 13 | "os/exec" 14 | "strings" 15 | "sync" 16 | "time" 17 | ) 18 | 19 | // Client is a client connection to Prisma Cloud. 20 | type Client struct { 21 | // Properties. 22 | Url string `json:"url"` 23 | Username string `json:"username"` 24 | Password string `json:"password"` 25 | CustomerName string `json:"customer_name"` 26 | Protocol string `json:"protocol"` 27 | Port int `json:"port"` 28 | Timeout int `json:"timeout"` 29 | SkipSslCertVerification bool `json:"skip_ssl_cert_verification"` 30 | Logging map[string]bool `json:"logging"` 31 | DisableReconnect bool `json:"disable_reconnect"` 32 | MaxRetries int `json:"max_retries"` 33 | RetryMaxDelay int `json:"retry_max_delay"` 34 | Retries sync.Map `json:"retries"` 35 | RetryType string `json:"retry_type"` 36 | 37 | // Advanced user config. 38 | Transport *http.Transport `json:"-"` 39 | 40 | // Set at runtime. 41 | JsonWebToken string `json:"json_web_token"` 42 | con *http.Client 43 | 44 | // Variables for testing. 45 | pcAuthFileContent []byte 46 | pcResponses []*http.Response 47 | pcResponseIndex int 48 | } 49 | 50 | // Method to generate a UUID for a resource 51 | func generateUUID() string { 52 | return uuid.New().String() 53 | } 54 | 55 | /* 56 | Initialize prepares the client connection and attempts a login. 57 | 58 | This function can be passed a credentials file to read in settings 59 | that will act as defaults if the given variables are currently unset. 60 | */ 61 | func (c *Client) Initialize(filename string) error { 62 | c2 := Client{} 63 | 64 | if filename != "" { 65 | var ( 66 | b []byte 67 | err error 68 | ) 69 | 70 | if len(c.pcResponses) == 0 { 71 | b, err = ioutil.ReadFile(filename) 72 | } else { 73 | b, err = c.pcAuthFileContent, nil 74 | } 75 | 76 | if err != nil { 77 | return err 78 | } 79 | 80 | if err = json.Unmarshal(b, &c2); err != nil { 81 | return err 82 | } 83 | } 84 | 85 | if len(c.Logging) == 0 { 86 | if len(c2.Logging) > 0 { 87 | c.Logging = make(map[string]bool) 88 | for key, val := range c2.Logging { 89 | c.Logging[key] = val 90 | } 91 | } else { 92 | c.Logging = map[string]bool{LogAction: true} 93 | } 94 | } 95 | 96 | var tout time.Duration 97 | if c.Timeout == 0 { 98 | if c2.Timeout > 0 { 99 | c.Timeout = c2.Timeout 100 | } else { 101 | c.Timeout = 180 102 | } 103 | } 104 | if c.Timeout < 0 { 105 | return fmt.Errorf("Invalid timeout") 106 | } 107 | tout = time.Duration(time.Duration(c.Timeout) * time.Second) 108 | 109 | if c.Port == 0 { 110 | if c2.Port != 0 { 111 | c.Port = c2.Port 112 | } 113 | } 114 | if c.Port > 65535 || c.Port < 0 { 115 | return fmt.Errorf("Invalid port number") 116 | } 117 | 118 | if c.Protocol == "" { 119 | if c2.Protocol != "" { 120 | c.Protocol = c2.Protocol 121 | } else { 122 | c.Protocol = "https" 123 | } 124 | } 125 | if c.Protocol != "http" && c.Protocol != "https" { 126 | return fmt.Errorf("Invalid protocol") 127 | } 128 | 129 | if c.Url == "" && c2.Url != "" { 130 | c.Url = c2.Url 131 | } 132 | if strings.HasPrefix(c.Url, "http://") || strings.HasPrefix(c.Url, "https://") { 133 | return fmt.Errorf("Specify protocol using the Protocol param, not as the URL") 134 | } 135 | c.Url = strings.TrimRight(c.Url, "/") 136 | if c.Url == "" { 137 | return fmt.Errorf("Prisma Cloud URL is not set") 138 | } 139 | 140 | if c.Username == "" && c2.Username != "" { 141 | c.Username = c2.Username 142 | } 143 | 144 | if c.Password == "" && c2.Password != "" { 145 | c.Password = c2.Password 146 | } 147 | 148 | if c.CustomerName == "" && c2.CustomerName != "" { 149 | c.CustomerName = c2.CustomerName 150 | } 151 | 152 | if c.Transport == nil { 153 | c.Transport = &http.Transport{ 154 | TLSClientConfig: &tls.Config{ 155 | InsecureSkipVerify: c.SkipSslCertVerification, 156 | }, 157 | Proxy: http.ProxyFromEnvironment, 158 | } 159 | } 160 | 161 | c.con = &http.Client{ 162 | Transport: c.Transport, 163 | Timeout: tout, 164 | } 165 | 166 | if c.JsonWebToken == "" && c2.JsonWebToken != "" { 167 | c.JsonWebToken = c2.JsonWebToken 168 | return nil 169 | } 170 | 171 | return c.Authenticate() 172 | } 173 | 174 | // Authenticate retrieves and saves a JSON web token from Prisma Cloud. 175 | func (c *Client) Authenticate() error { 176 | var err error 177 | 178 | type initial struct { 179 | Username string `json:"username"` 180 | Password string `json:"password"` 181 | CustomerName string `json:"customerName,omitempty"` 182 | } 183 | 184 | ans := AuthResponse{} 185 | 186 | /* 187 | Ideally we would do a JSON web token refresh if we got one 188 | previously, but just straight up performing a re-authentication 189 | always works. So just do a full login again if we have the 190 | username and password, falling back to a token refresh. 191 | */ 192 | resourceUUID := generateUUID() 193 | if c.Username != "" && c.Password != "" { 194 | c.Log(LogAction, "(auth) retrieving jwt") 195 | req := initial{c.Username, c.Password, c.CustomerName} 196 | _, err = c.communicate("POST", []string{"login"}, nil, &req, &ans, false, resourceUUID) 197 | } else if c.JsonWebToken != "" { 198 | c.Log(LogAction, "(auth) refreshing jwt") 199 | _, err = c.communicate("GET", []string{"auth_token", "extend"}, nil, nil, &ans, false, "") 200 | } else { 201 | return fmt.Errorf("no authentication params given") 202 | } 203 | 204 | if err != nil { 205 | return err 206 | } 207 | 208 | c.JsonWebToken = ans.Token 209 | return nil 210 | } 211 | 212 | /* 213 | Communicate handles basic communication with Prisma Cloud. 214 | 215 | If a non-nil interface is given as the "ans" variable, then this function 216 | will unmarshal the returned JSON into it, and you can safely discard the 217 | slice of bytes returned. 218 | */ 219 | func (c *Client) Communicate(method string, suffix []string, query, data interface{}, ans interface{}) ([]byte, error) { 220 | resourceUUID := generateUUID() 221 | return c.communicate(method, suffix, query, data, ans, true, resourceUUID) 222 | } 223 | 224 | // Log logs a message to the user if the appropriate style is enabled. 225 | func (c *Client) Log(flag, msg string, i ...interface{}) { 226 | if c.Logging[flag] { 227 | log.Printf(msg, i...) 228 | } 229 | } 230 | 231 | func (c *Client) do(req *http.Request) (*http.Response, error) { 232 | if len(c.pcResponses) == 0 { 233 | return c.con.Do(req) 234 | } 235 | 236 | resp := c.pcResponses[c.pcResponseIndex] 237 | c.pcResponseIndex++ 238 | return resp, nil 239 | } 240 | 241 | // logSendReceive outputs raw data sent and received, but tries to 242 | // remove sensitive information from being printed. 243 | func (c *Client) logSendReceive(logFlag string, code int, b []byte) { 244 | var desc string 245 | 246 | switch logFlag { 247 | case LogSend: 248 | desc = "sending:\n" 249 | case LogReceive: 250 | desc = fmt.Sprintf("received (%d):", code) 251 | default: 252 | return 253 | } 254 | 255 | if !c.Logging[logFlag] { 256 | return 257 | } else if len(b) == 0 { 258 | log.Printf("%s", desc) 259 | return 260 | } 261 | 262 | var ti interface{} 263 | if err := json.Unmarshal(b, &ti); err != nil { 264 | log.Printf("failed to unmarshal %s: %s", logFlag, err) 265 | log.Printf("%s\n%s", desc, scrubSensitiveData(b)) 266 | return 267 | } 268 | 269 | b2, _ := json.MarshalIndent(ti, "", " ") 270 | log.Printf("%s\n%s", desc, scrubSensitiveData(b2)) 271 | } 272 | 273 | func (c *Client) communicate(method string, suffix []string, query, data interface{}, ans interface{}, allowRetry bool, resourceUUID string) ([]byte, error) { 274 | var err error 275 | var buf bytes.Buffer 276 | 277 | retriesInterface, _ := c.Retries.LoadOrStore(resourceUUID, 0) 278 | retries := retriesInterface.(int) 279 | 280 | if data != nil { 281 | b, err := json.Marshal(data) 282 | if err != nil { 283 | return nil, err 284 | } 285 | buf = *bytes.NewBuffer(b) 286 | c.logSendReceive(LogSend, 0, b) 287 | } 288 | 289 | var path strings.Builder 290 | path.Grow(30) 291 | fmt.Fprintf(&path, "%s://%s", c.Protocol, c.Url) 292 | if c.Port != 0 { 293 | fmt.Fprintf(&path, ":%d", c.Port) 294 | } 295 | for _, v := range suffix { 296 | path.WriteString("/") 297 | path.WriteString(v) 298 | } 299 | if query != nil { 300 | qv := query.(url.Values) 301 | path.WriteString("?") 302 | path.WriteString(qv.Encode()) 303 | } 304 | c.Log(LogPath, "path: %s", path.String()) 305 | 306 | req, err := http.NewRequest(method, path.String(), &buf) 307 | if err != nil { 308 | return nil, err 309 | } 310 | 311 | req.Header.Set("Content-Type", "application/json") 312 | newUUID, err := exec.Command("uuidgen").Output() 313 | uuid := strings.TrimSpace(string(newUUID)) 314 | uuidPC := "PrismaCloud-terraform-" + uuid 315 | req.Header.Set("terraform-request-identifier", uuidPC) 316 | if c.JsonWebToken != "" { 317 | req.Header.Set("x-redlock-auth", c.JsonWebToken) 318 | } 319 | 320 | resp, err := c.do(req) 321 | if err != nil { 322 | return nil, err 323 | } 324 | 325 | defer resp.Body.Close() 326 | body, err := ioutil.ReadAll(resp.Body) 327 | if err != nil { 328 | return nil, err 329 | } 330 | c.logSendReceive(LogReceive, resp.StatusCode, []byte(body)) 331 | 332 | requestId := "X-Redlock-Request-Id" 333 | traceId := "Trace-Id" 334 | log.Printf("X-Redlock-Request-Id : %v Trace-Id : %v Status-Code: %d for path: %s terraform-request-identifier : %v", resp.Header[requestId], resp.Header[traceId], resp.StatusCode, path.String(), uuidPC) 335 | 336 | switch resp.StatusCode { 337 | case http.StatusOK, http.StatusNoContent, http.StatusCreated: 338 | c.Retries.Delete(resourceUUID) 339 | // Alert rule deletion returns StatusNoContent 340 | case http.StatusUnauthorized: 341 | if !c.DisableReconnect && allowRetry { 342 | log.Println("Trying to re-authenticate") 343 | if err = c.Authenticate(); err == nil { 344 | log.Println("Re-authentication successfull") 345 | return c.communicate(method, suffix, query, data, ans, false, resourceUUID) 346 | } 347 | } 348 | return body, InvalidCredentialsError 349 | case http.StatusTooManyRequests: 350 | var delay int 351 | retries++ 352 | if c.RetryType == "exponential_backoff" { 353 | delay = 1 << retries 354 | } else if c.RetryType == "linear_backoff" { 355 | delay = 1 + retries 356 | } 357 | 358 | if delay <= c.RetryMaxDelay && delay > 0 && retries <= c.MaxRetries { 359 | log.Printf("API received too many requests, retrying") 360 | time.Sleep(time.Duration(delay) * time.Second) 361 | c.MaxRetries = c.MaxRetries - 1 362 | c.Retries.Store(resourceUUID, retries) 363 | return c.communicate(method, suffix, query, data, ans, true, resourceUUID) 364 | } else if delay > c.RetryMaxDelay || c.MaxRetries <= 0 { 365 | return nil, fmt.Errorf("max_retries or retry_max_delay insufficient") 366 | } 367 | default: 368 | errLocation := "X-Redlock-Status" 369 | if _, ok := resp.Header[errLocation]; !ok { 370 | return body, fmt.Errorf("%d error without the %q header - returned HTML:\n%s", resp.StatusCode, errLocation, body) 371 | } 372 | pcel := PrismaCloudErrorList{ 373 | Method: method, 374 | StatusCode: resp.StatusCode, 375 | Path: path.String(), 376 | } 377 | info := resp.Header[errLocation][0] 378 | if err = json.Unmarshal([]byte(info), &pcel.Errors); err != nil { 379 | return body, fmt.Errorf("%d error, and could not unmarshal header %q: %s", resp.StatusCode, info, err) 380 | } 381 | if ce := pcel.GenericError(); ce != nil { 382 | return body, ce 383 | } 384 | return body, pcel 385 | } 386 | 387 | if ans != nil { 388 | if err = json.Unmarshal(body, ans); err != nil { 389 | return body, err 390 | } 391 | } 392 | 393 | return body, nil 394 | } 395 | -------------------------------------------------------------------------------- /client_test.go: -------------------------------------------------------------------------------- 1 | package prismacloud 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "io/ioutil" 7 | "log" 8 | "net/http" 9 | "net/url" 10 | "os" 11 | "strings" 12 | "testing" 13 | ) 14 | 15 | var TestPath = []string{"test", "path"} 16 | 17 | var GenericAuthFile = []byte(`{ 18 | "url": "api.prismacloud.io", 19 | "username": "defaultUser", 20 | "password": "defaultPassword", 21 | "customer_name": "defaultCustomer", 22 | "skip_ssl_cert_verification": true, 23 | "logging": {"quiet": true} 24 | } 25 | `) 26 | 27 | var LoginBody = `{ 28 | "customerNames": [ 29 | { 30 | "customerName": "RedLockDemo", 31 | "tosAccepted": true 32 | }, 33 | { 34 | "customerName": "SESandBox", 35 | "tosAccepted": true 36 | } 37 | ], 38 | "message": "login_successful", 39 | "token": "testJwtToken" 40 | }` 41 | 42 | func init() { 43 | log.SetFlags(0) 44 | } 45 | 46 | func rl() { 47 | log.SetOutput(os.Stderr) 48 | } 49 | 50 | func OkResponse(body string) *http.Response { 51 | return &http.Response{ 52 | StatusCode: 200, 53 | Body: ioutil.NopCloser( 54 | strings.NewReader(body), 55 | ), 56 | } 57 | } 58 | 59 | func ErrorResponse(code int, body string, e interface{}) *http.Response { 60 | ans := &http.Response{ 61 | StatusCode: code, 62 | Body: ioutil.NopCloser( 63 | strings.NewReader(body), 64 | ), 65 | } 66 | 67 | if e != nil { 68 | errBody, _ := json.Marshal(e) 69 | ans.Header = map[string][]string{ 70 | "X-Redlock-Status": []string{ 71 | "[" + string(errBody) + "]", 72 | }, 73 | } 74 | } 75 | 76 | return ans 77 | } 78 | 79 | func MockClient(responses []*http.Response) Client { 80 | c := Client{ 81 | pcAuthFileContent: GenericAuthFile, 82 | } 83 | 84 | c.pcResponses = make([]*http.Response, 0, len(responses)+1) 85 | c.pcResponses = append(c.pcResponses, OkResponse(LoginBody)) 86 | c.pcResponses = append(c.pcResponses, responses...) 87 | 88 | if len(responses) > 0 { 89 | _ = c.Initialize("test") 90 | } 91 | 92 | return c 93 | } 94 | 95 | func TestLogin(t *testing.T) { 96 | c := MockClient(nil) 97 | err := c.Initialize("test") 98 | 99 | if err != nil { 100 | t.Fail() 101 | } 102 | } 103 | 104 | func TestInitializeSetsJwt(t *testing.T) { 105 | c := MockClient(nil) 106 | _ = c.Initialize("test") 107 | 108 | if c.JsonWebToken == "" { 109 | t.Fail() 110 | } 111 | } 112 | 113 | func TestInitializeReadsDefaults(t *testing.T) { 114 | var buf bytes.Buffer 115 | log.SetOutput(&buf) 116 | defer rl() 117 | 118 | c := MockClient(nil) 119 | c.Url = "testurl" 120 | c.Username = "user" 121 | c.Password = "secret" 122 | _ = c.Initialize("") 123 | 124 | if c.Protocol == "" { 125 | t.Fail() 126 | } 127 | 128 | if c.Timeout == 0 { 129 | t.Fail() 130 | } 131 | 132 | if len(c.Logging) == 0 { 133 | t.Fail() 134 | } 135 | 136 | s := buf.String() 137 | if s == "" { 138 | t.Fail() 139 | } 140 | } 141 | 142 | func TestLogAction(t *testing.T) { 143 | var buf bytes.Buffer 144 | log.SetOutput(&buf) 145 | defer rl() 146 | 147 | c := MockClient(nil) 148 | c.Logging = map[string]bool{LogAction: true} 149 | c.Log(LogAction, "ok") 150 | s := buf.String() 151 | if s != "ok\n" { 152 | t.Fail() 153 | } 154 | } 155 | 156 | func TestLogActionDisabled(t *testing.T) { 157 | var buf bytes.Buffer 158 | log.SetOutput(&buf) 159 | defer rl() 160 | 161 | c := MockClient(nil) 162 | c.Logging = map[string]bool{LogQuiet: true} 163 | c.Log(LogAction, "ok") 164 | s := buf.String() 165 | if s != "" { 166 | t.Fail() 167 | } 168 | } 169 | 170 | func TestPathWithQuery(t *testing.T) { 171 | var buf bytes.Buffer 172 | log.SetOutput(&buf) 173 | defer rl() 174 | 175 | c := MockClient( 176 | []*http.Response{ 177 | OkResponse(""), 178 | }, 179 | ) 180 | c.Logging[LogPath] = true 181 | 182 | v := url.Values{} 183 | v.Set("foo", "bar") 184 | 185 | _, err := c.Communicate("GET", TestPath, v, nil, nil) 186 | if err != nil { 187 | t.Fail() 188 | } 189 | 190 | //expected := "X-Redlock-Request-Id : [] Trace-Id : [] for path: https://api.prismacloud.io/login terraform-request-identifier : PrismaCloud-terraform-fa918d43-087c-486e-8d13-06e7f882f3a3\npath: https://api.prismacloud.io/test/path?foo=bar\nX-Redlock-Request-Id : [] Trace-Id : [] for path: https://api.prismacloud.io/test/path?foo=bar terraform-request-identifier : PrismaCloud-terraform-3b630210-6c9d-4026-b09a-5c25b60a2752\n" 191 | //if buf.String() != expected { 192 | // t.Errorf("expected:%q got:%q", expected, buf.String()) 193 | //} 194 | } 195 | 196 | func TestPathWithoutQuery(t *testing.T) { 197 | var buf bytes.Buffer 198 | log.SetOutput(&buf) 199 | defer rl() 200 | 201 | c := MockClient( 202 | []*http.Response{ 203 | OkResponse(""), 204 | }, 205 | ) 206 | c.Logging[LogPath] = true 207 | 208 | _, err := c.Communicate("GET", TestPath, nil, nil, nil) 209 | if err != nil { 210 | t.Fail() 211 | } 212 | 213 | //expected := "X-Redlock-Request-Id : [] Trace-Id : [] for path: https://api.prismacloud.io/login terraform-request-identifier : PrismaCloud-terraform-8f5643c9-d877-481f-b5f5-9f7989ce7770\npath: https://api.prismacloud.io/test/path\nX-Redlock-Request-Id : [] Trace-Id : [] for path: https://api.prismacloud.io/test/path terraform-request-identifier : PrismaCloud-terraform-97e36386-5013-4d1a-94f1-8525aad20b84\n" 214 | //if buf.String() != expected { 215 | // t.Errorf("expected:%q got:%q", expected, buf.String()) 216 | //} 217 | } 218 | 219 | func TestReauthenticateHappens(t *testing.T) { 220 | expected := "okay" 221 | c := MockClient( 222 | []*http.Response{ 223 | ErrorResponse(http.StatusUnauthorized, "", nil), 224 | OkResponse(LoginBody), 225 | OkResponse(expected), 226 | }, 227 | ) 228 | c.JsonWebToken = "oldToken" 229 | 230 | body, err := c.Communicate("GET", TestPath, nil, nil, nil) 231 | if err != nil { 232 | t.Errorf("Failed communicate: %s", err) 233 | } 234 | 235 | if string(body) != expected { 236 | t.Errorf("expected %q, got %q", expected, string(body)) 237 | } 238 | 239 | if c.JsonWebToken == "oldToken" { 240 | t.Fail() 241 | } 242 | } 243 | 244 | func TestAlreadyExists(t *testing.T) { 245 | c := MockClient( 246 | []*http.Response{ 247 | ErrorResponse( 248 | http.StatusTeapot, 249 | "", 250 | PrismaCloudError{ 251 | Message: "teapot_already_exists", 252 | Severity: "error", 253 | }, 254 | ), 255 | }, 256 | ) 257 | 258 | _, err := c.Communicate("GET", TestPath, nil, nil, nil) 259 | if err == nil { 260 | t.Fail() 261 | } 262 | 263 | if err != AlreadyExistsError { 264 | t.Errorf("error is %s, not %s", err, AlreadyExistsError) 265 | } 266 | } 267 | 268 | func TestInvalidCredentialsError(t *testing.T) { 269 | c := MockClient( 270 | []*http.Response{ 271 | ErrorResponse(http.StatusUnauthorized, "", nil), 272 | ErrorResponse(http.StatusUnauthorized, "", nil), 273 | }, 274 | ) 275 | 276 | _, err := c.Communicate("GET", TestPath, nil, nil, nil) 277 | if err == nil { 278 | t.Fail() 279 | } 280 | 281 | if err != InvalidCredentialsError { 282 | t.Errorf("error is %s, not %s", err, InvalidCredentialsError) 283 | } 284 | } 285 | 286 | func TestObjectNotFoundError(t *testing.T) { 287 | c := MockClient( 288 | []*http.Response{ 289 | ErrorResponse( 290 | http.StatusTeapot, 291 | "", 292 | PrismaCloudError{ 293 | Message: "not_found", 294 | Severity: "error", 295 | }, 296 | ), 297 | }, 298 | ) 299 | 300 | _, err := c.Communicate("GET", TestPath, nil, nil, nil) 301 | if err == nil { 302 | t.Fail() 303 | } 304 | 305 | if err != ObjectNotFoundError { 306 | t.Errorf("error is %s, not %s", err, ObjectNotFoundError) 307 | } 308 | } 309 | 310 | func TestInvalidResponse(t *testing.T) { 311 | expectedHtml := ` 312 | 313 |

nope

314 | 315 | ` 316 | c := MockClient( 317 | []*http.Response{ 318 | ErrorResponse(http.StatusTeapot, expectedHtml, nil), 319 | }, 320 | ) 321 | 322 | data, err := c.Communicate("GET", TestPath, nil, nil, nil) 323 | if string(data) != expectedHtml { 324 | t.Errorf("Expected:%s got:%s", expectedHtml, data) 325 | } 326 | 327 | if err == nil { 328 | t.Errorf("No error returned") 329 | } 330 | 331 | if !strings.HasSuffix(err.Error(), expectedHtml) { 332 | t.Errorf("Error doesn't have expected suffix:\n%s", err) 333 | } 334 | } 335 | -------------------------------------------------------------------------------- /cloud/account-v2/azureTemplate/const.go: -------------------------------------------------------------------------------- 1 | package azureTemplate 2 | 3 | var Suffix = []string{"cas/v1/azure_template"} 4 | -------------------------------------------------------------------------------- /cloud/account-v2/azureTemplate/funcs.go: -------------------------------------------------------------------------------- 1 | package azureTemplate 2 | 3 | import ( 4 | "fmt" 5 | pc "github.com/paloaltonetworks/prisma-cloud-go" 6 | "os" 7 | ) 8 | 9 | func GetAzureTemplate(c pc.PrismaCloudClient, req AzureTemplateReq) error { 10 | 11 | filename := req.FileName 12 | filename = filename + ".tf.json" 13 | 14 | path := make([]string, 0, len(Suffix)+1) 15 | path = append(path, Suffix...) 16 | resp, err := c.Communicate("POST", path, nil, req, nil) 17 | if err != nil { 18 | return err 19 | } 20 | file, err := os.OpenFile(filename, os.O_TRUNC|os.O_CREATE|os.O_RDWR, 0777) 21 | if err != nil { 22 | return fmt.Errorf("Invalid path: %s", filename) 23 | } 24 | 25 | _, err = file.Write(resp) 26 | if err != nil { 27 | return err 28 | } 29 | file.Close() 30 | return err 31 | 32 | } 33 | -------------------------------------------------------------------------------- /cloud/account-v2/azureTemplate/structs.go: -------------------------------------------------------------------------------- 1 | package azureTemplate 2 | 3 | type AzureTemplateReq struct { 4 | SubscriptionId string `json:"subscriptionId"` 5 | TenantId string `json:"tenantId"` 6 | AccountType string `json:"accountType"` 7 | DeploymentType string `json:"deploymentType"` 8 | RootSyncEnabled bool `json:"rootSyncEnabled"` 9 | Features []string `json:"features"` 10 | FileName string `json:"fileName"` 11 | } 12 | 13 | type AzureTemplate struct { 14 | SubscriptionId string `json:"subscriptionId"` 15 | TenantId string `json:"tenantId"` 16 | AccountType string `json:"accountType"` 17 | DeploymentType string `json:"deploymentType"` 18 | RootSyncEnabled bool `json:"rootSyncEnabled"` 19 | Features []string `json:"features"` 20 | FileName string `json:"fileName"` 21 | } 22 | -------------------------------------------------------------------------------- /cloud/account-v2/const.go: -------------------------------------------------------------------------------- 1 | package accountv2 2 | 3 | const ( 4 | singular = "cloud account" 5 | plural = "cloud accounts" 6 | ) 7 | 8 | var DeleteSuffix = []string{"cloud"} 9 | 10 | var Suffix = []string{"cas", "v1"} 11 | 12 | var ListSuffix = []string{"v1", "cloudAccounts"} 13 | 14 | var ListSuffixAws = []string{"v1", "cloudAccounts", "awsAccounts"} 15 | 16 | var ListSuffixAzure = []string{"v1", "cloudAccounts", "azureAccounts"} 17 | 18 | var ListSuffixGcp = []string{"cas", "v1", "cloud_account", "gcp"} 19 | 20 | var ListSuffixIbm = []string{"cas", "v1", "cloud_account", "ibm"} 21 | 22 | var AlibabaSuffix = []string{"cloud"} 23 | 24 | const ( 25 | TypeAws = "aws" 26 | TypeAzure = "azure" 27 | TypeGcp = "gcp" 28 | TypeIbm = "ibm" 29 | TypeAlibaba = "alibaba_cloud" 30 | ) 31 | -------------------------------------------------------------------------------- /cloud/account-v2/externalid/const.go: -------------------------------------------------------------------------------- 1 | package externalid 2 | 3 | var Suffix = []string{"cas/v1/aws_template/presigned_url"} 4 | 5 | var StorageUUIDSuffix = []string{"pcds/config/v3/cloudTrail"} 6 | -------------------------------------------------------------------------------- /cloud/account-v2/externalid/funcs.go: -------------------------------------------------------------------------------- 1 | package externalid 2 | 3 | import ( 4 | pc "github.com/paloaltonetworks/prisma-cloud-go" 5 | ) 6 | 7 | func GetExternalId(c pc.PrismaCloudClient, req ExternalIdReq) (ExternalId, error) { 8 | c.Log(pc.LogAction, "(post) performing external id") 9 | 10 | var resp ExternalId 11 | 12 | _, err := c.Communicate("POST", Suffix, nil, req, &resp) 13 | return resp, err 14 | } 15 | 16 | func GetStorageUUID(c pc.PrismaCloudClient, req StorageUUID) (StorageUUID, error) { 17 | c.Log(pc.LogAction, "(post) getting storage_uuid") 18 | 19 | var resp StorageUUID 20 | 21 | _, err := c.Communicate("POST", StorageUUIDSuffix, nil, req, &resp) 22 | return resp, err 23 | } 24 | -------------------------------------------------------------------------------- /cloud/account-v2/externalid/structs.go: -------------------------------------------------------------------------------- 1 | package externalid 2 | 3 | type ExternalIdReq struct { 4 | AccountId string `json:"accountId"` 5 | AccountType string `json:"accountType"` 6 | AwsPartition string `json:"awsPartition"` 7 | Features []string `json:"features"` 8 | } 9 | 10 | type ExternalId struct { 11 | AccountId string `json:"accountId"` 12 | AccountType string `json:"accountType"` 13 | AwsPartition string `json:"awsPartition"` 14 | Features Features1 `json:"features"` 15 | ExternalId string `json:"externalId"` 16 | CreateStackLinkWithS3PresignedUrl string `json:"createStackLinkWithS3PresignedUrl"` 17 | EventBridgeRuleNamePrefix string `json:"eventBridgeRuleNamePrefix"` 18 | } 19 | 20 | type Features1 struct { 21 | Name string `json:"featureName"` 22 | State string `json:"featureState"` 23 | } 24 | 25 | type StorageUUID struct { 26 | AccountId string `json:"accountId"` 27 | ExternalId string `json:"externalId"` 28 | RoleArn string `json:"roleArn"` 29 | StorageUUID string `json:"storageUUID"` 30 | } 31 | -------------------------------------------------------------------------------- /cloud/account-v2/funcs.go: -------------------------------------------------------------------------------- 1 | package accountv2 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | pc "github.com/paloaltonetworks/prisma-cloud-go" 8 | ) 9 | 10 | // List lists all cloud accounts onboarded onto the Prisma Cloud platform. 11 | func List(c pc.PrismaCloudClient) ([]AccountResponse, error) { 12 | c.Log(pc.LogAction, "(get) list of %s", plural) 13 | 14 | var ans []AccountResponse 15 | if _, err := c.Communicate("GET", ListSuffixAws, nil, nil, &ans); err != nil { 16 | return nil, err 17 | } 18 | 19 | return ans, nil 20 | } 21 | 22 | func ListAzure(c pc.PrismaCloudClient) ([]AzureAccountResponse, error) { 23 | c.Log(pc.LogAction, "(get) list of %s", plural) 24 | 25 | var ansaz []AzureAccountResponse 26 | if _, err := c.Communicate("GET", ListSuffixAzure, nil, nil, &ansaz); err != nil { 27 | return nil, err 28 | } 29 | 30 | return ansaz, nil 31 | } 32 | 33 | func ListGcp(c pc.PrismaCloudClient) ([]GcpAccountResponse, error) { 34 | c.Log(pc.LogAction, "(get) list of %s", plural) 35 | 36 | var ansgcp []GcpAccountResponse 37 | if _, err := c.Communicate("GET", ListSuffixGcp, nil, nil, &ansgcp); err != nil { 38 | return nil, err 39 | } 40 | 41 | return ansgcp, nil 42 | } 43 | 44 | func ListIbm(c pc.PrismaCloudClient) ([]IbmAccountResponse, error) { 45 | c.Log(pc.LogAction, "(get) list of %s", plural) 46 | path := make([]string, 0, len(ListSuffix)+1) 47 | path = append(path, ListSuffix...) 48 | path = append(path, "accounts?cloudTypes=ibm") 49 | 50 | var ansib []IbmAccountResponse 51 | if _, err := c.Communicate("GET", path, nil, nil, &ansib); err != nil { 52 | return nil, err 53 | } 54 | 55 | return ansib, nil 56 | } 57 | 58 | func ListAlibaba(c pc.PrismaCloudClient) ([]AlibabaAccountResponse, error) { 59 | c.Log(pc.LogAction, "(get) list of %s", plural) 60 | 61 | var ansalibaba []AlibabaAccountResponse 62 | if _, err := c.Communicate("GET", AlibabaSuffix, nil, nil, &ansalibaba); err != nil { 63 | return nil, err 64 | } 65 | return ansalibaba, nil 66 | } 67 | 68 | // Names returns the name listing for cloud accounts. 69 | func Names(c pc.PrismaCloudClient) ([]NameTypeId, error) { 70 | c.Log(pc.LogAction, "(get) %s names", singular) 71 | 72 | path := make([]string, 0, len(Suffix)+1) 73 | path = append(path, Suffix...) 74 | path = append(path, "name") 75 | 76 | var ans []NameTypeId 77 | _, err := c.Communicate("GET", path, nil, nil, &ans) 78 | 79 | return ans, err 80 | } 81 | 82 | // Identify returns the ID for the given cloud type and name. 83 | func Identify(c pc.PrismaCloudClient, cloudType, name string) (string, error) { 84 | c.Log(pc.LogAction, "(get) id for %s type:%s name:%s", singular, cloudType, name) 85 | if cloudType == "aws" { 86 | ans, err := List(c) 87 | if err != nil { 88 | return "", err 89 | } 90 | 91 | for _, o := range ans { 92 | if strings.EqualFold(o.CloudAccountResp.CloudType, cloudType) && o.CloudAccountResp.Name == name { 93 | return o.CloudAccountResp.AccountId, nil 94 | } 95 | 96 | } 97 | } 98 | if strings.EqualFold("azure", cloudType) { 99 | ansaz, err := ListAzure(c) 100 | if err != nil { 101 | return "", err 102 | } 103 | 104 | for _, o := range ansaz { 105 | if strings.EqualFold(o.CloudAccountAzureResp.CloudType, cloudType) && o.CloudAccountAzureResp.Name == name { 106 | return o.CloudAccountAzureResp.AccountId, nil 107 | } 108 | 109 | } 110 | } 111 | if strings.EqualFold("gcp", cloudType) { 112 | ansgcp, err := ListGcp(c) 113 | if err != nil { 114 | return "", err 115 | } 116 | 117 | for _, o := range ansgcp { 118 | if strings.EqualFold(o.CloudType, cloudType) && o.Name == name { 119 | return o.AccountId, nil 120 | } 121 | 122 | } 123 | } 124 | if strings.EqualFold("ibm", cloudType) { 125 | ansib, err := ListIbm(c) 126 | if err != nil { 127 | return "", err 128 | } 129 | 130 | for _, o := range ansib { 131 | if strings.EqualFold(o.CloudType, cloudType) && o.Name == name { 132 | return o.AccountId, nil 133 | } 134 | 135 | } 136 | } 137 | if strings.EqualFold("alibaba_cloud", cloudType) { 138 | ansalibaba, err := ListAlibaba(c) 139 | if err != nil { 140 | return "", err 141 | } 142 | for _, o := range ansalibaba { 143 | if strings.EqualFold(o.CloudType, cloudType) && o.Name == name { 144 | return o.AccountId, nil 145 | } 146 | 147 | } 148 | } 149 | 150 | return "", pc.ObjectNotFoundError 151 | } 152 | 153 | func Get(c pc.PrismaCloudClient, cloudType, id string) (interface{}, error) { 154 | var cloud string 155 | cloud = cloudType 156 | cloud = cloud + "Accounts" 157 | c.Log(pc.LogAction, "(get) %s type:%s id:%s", singular, cloudType, id) 158 | 159 | if cloudType == "gcp" { 160 | path := make([]string, 0, len(ListSuffixGcp)+1) 161 | path = append(path, ListSuffixGcp...) 162 | path = append(path, id) 163 | var ans interface{} 164 | 165 | switch cloudType { 166 | case TypeGcp: 167 | ans = &GcpV2{} 168 | default: 169 | return nil, fmt.Errorf("Invalid cloud type: %s", cloudType) 170 | } 171 | _, err := c.Communicate("GET", path, nil, nil, ans) 172 | 173 | switch cloudType { 174 | case TypeGcp: 175 | return *ans.(*GcpV2), err 176 | } 177 | } else if cloudType == "ibm" { 178 | path := make([]string, 0, len(ListSuffixIbm)+1) 179 | path = append(path, ListSuffixIbm...) 180 | path = append(path, id) 181 | 182 | var ans interface{} 183 | 184 | switch cloudType { 185 | case TypeIbm: 186 | ans = &IbmV2{} 187 | default: 188 | return nil, fmt.Errorf("Invalid cloud type: %s", cloudType) 189 | } 190 | _, err := c.Communicate("GET", path, nil, nil, ans) 191 | 192 | switch cloudType { 193 | case TypeIbm: 194 | return *ans.(*IbmV2), err 195 | } 196 | } else if cloudType == "alibaba_cloud" { 197 | path := make([]string, 0, len(AlibabaSuffix)+2) 198 | path = append(path, AlibabaSuffix...) 199 | path = append(path, cloudType, id) 200 | 201 | var ans interface{} 202 | 203 | switch cloudType { 204 | case TypeAlibaba: 205 | ans = &AlibabaV2{} 206 | default: 207 | return nil, fmt.Errorf("Invalid cloud type: %s", cloudType) 208 | } 209 | 210 | _, err := c.Communicate("GET", path, nil, nil, ans) 211 | 212 | switch cloudType { 213 | case TypeAlibaba: 214 | return *ans.(*AlibabaV2), err 215 | } 216 | 217 | } else { 218 | path := make([]string, 0, len(ListSuffix)+1) 219 | path = append(path, ListSuffix...) 220 | path = append(path, cloud, id) 221 | var ans interface{} 222 | 223 | switch cloudType { 224 | case TypeAws: 225 | ans = &AwsV2{} 226 | case TypeAzure: 227 | ans = &AzureV2{} 228 | default: 229 | return nil, fmt.Errorf("Invalid cloud type: %s", cloudType) 230 | } 231 | _, err := c.Communicate("GET", path, nil, nil, ans) 232 | 233 | switch cloudType { 234 | case TypeAws: 235 | return *ans.(*AwsV2), err 236 | case TypeAzure: 237 | return *ans.(*AzureV2), err 238 | } 239 | 240 | } 241 | return nil, fmt.Errorf("Invalid cloud type: %s", cloudType) 242 | 243 | } 244 | 245 | // Create onboards a new cloud account onto the Prisma Cloud platform. 246 | func Create(c pc.PrismaCloudClient, account interface{}) error { 247 | return createUpdate(false, c, account) 248 | } 249 | 250 | // Update modifies information related to a cloud account. 251 | func Update(c pc.PrismaCloudClient, account interface{}) error { 252 | return createUpdate(true, c, account) 253 | } 254 | 255 | // Delete removes an onboarded cloud account using the cloud account ID. 256 | func Delete(c pc.PrismaCloudClient, cloudType, id string) error { 257 | c.Log(pc.LogAction, "(delete) %s type:%s id:%s", singular, cloudType, id) 258 | 259 | path := make([]string, 0, len(DeleteSuffix)+2) 260 | path = append(path, DeleteSuffix...) 261 | path = append(path, cloudType, id) 262 | _, err := c.Communicate("DELETE", path, nil, nil, nil) 263 | return err 264 | } 265 | 266 | func DisableCloudAccount(c pc.PrismaCloudClient, accountId string) error { 267 | var ( 268 | method string 269 | ) 270 | method = "PATCH" 271 | 272 | path := make([]string, 0, len(Suffix)+1) 273 | path = append(path, "cloud") 274 | path = append(path, accountId) 275 | path = append(path, "status") 276 | path = append(path, "false") 277 | 278 | _, err := c.Communicate(method, path, nil, nil, nil) 279 | return err 280 | } 281 | 282 | func createUpdate(exists bool, c pc.PrismaCloudClient, account interface{}) error { 283 | var ( 284 | logMsg strings.Builder 285 | id string 286 | method string 287 | cloudType string 288 | ) 289 | 290 | logMsg.Grow(30) 291 | logMsg.WriteString("(") 292 | if exists { 293 | logMsg.WriteString("update") 294 | method = "PUT" 295 | } else { 296 | logMsg.WriteString("create") 297 | method = "POST" 298 | } 299 | logMsg.WriteString(") ") 300 | 301 | switch v := account.(type) { 302 | case nil: 303 | return fmt.Errorf("Cloud account specified") 304 | case Aws: 305 | logMsg.WriteString("aws") 306 | cloudType = TypeAws 307 | id = v.AccountId 308 | case AwsStorageScan: 309 | logMsg.WriteString("aws") 310 | cloudType = TypeAws 311 | id = v.AccountId 312 | case Azure: 313 | logMsg.WriteString("azure") 314 | cloudType = TypeAzure 315 | id = v.CloudAccountAzure.AccountId 316 | case Gcp: 317 | logMsg.WriteString("gcp") 318 | cloudType = TypeGcp 319 | id = v.CloudAccountGcp.AccountId 320 | case Ibm: 321 | logMsg.WriteString("ibm") 322 | cloudType = TypeIbm 323 | id = v.AccountId 324 | case Alibaba: 325 | logMsg.WriteString("alibaba") 326 | cloudType = TypeAlibaba 327 | id = v.AccountId 328 | default: 329 | return fmt.Errorf("invalid account type %v", v) 330 | } 331 | 332 | logMsg.WriteString(" ") 333 | logMsg.WriteString(singular) 334 | if exists { 335 | fmt.Fprintf(&logMsg, ": %s", id) 336 | } 337 | 338 | c.Log(pc.LogAction, logMsg.String()) 339 | if cloudType == "ibm" { 340 | path := make([]string, 0, len(Suffix)+1) 341 | path = append(path, Suffix...) 342 | path = append(path, "cloud-type") 343 | path = append(path, "ibm") 344 | path = append(path, "account") 345 | if exists { 346 | path = append(path, id) 347 | } 348 | _, err := c.Communicate(method, path, nil, account, nil) 349 | return err 350 | } else if cloudType == "alibaba_cloud" { 351 | path := make([]string, 0, len(AlibabaSuffix)+2) 352 | path = append(path, AlibabaSuffix...) 353 | path = append(path, cloudType) 354 | if exists { 355 | path = append(path, id) 356 | } 357 | 358 | _, err := c.Communicate(method, path, nil, account, nil) 359 | return err 360 | } else { 361 | path := make([]string, 0, len(Suffix)+1) 362 | path = append(path, Suffix...) 363 | cloudType = cloudType + "_account" 364 | path = append(path, cloudType) 365 | if exists { 366 | path = append(path, id) 367 | } 368 | _, err := c.Communicate(method, path, nil, account, nil) 369 | return err 370 | } 371 | } 372 | -------------------------------------------------------------------------------- /cloud/account-v2/gcpTemplate/const.go: -------------------------------------------------------------------------------- 1 | package gcpTemplate 2 | 3 | var Suffix = []string{"cas/v1/gcp_template"} 4 | -------------------------------------------------------------------------------- /cloud/account-v2/gcpTemplate/funcs.go: -------------------------------------------------------------------------------- 1 | package gcpTemplate 2 | 3 | import ( 4 | "fmt" 5 | pc "github.com/paloaltonetworks/prisma-cloud-go" 6 | "os" 7 | ) 8 | 9 | func GetGcpTemplate(c pc.PrismaCloudClient, req GcpTemplateReq) error { 10 | 11 | filename := req.FileName 12 | filename = filename + ".tf.json" 13 | 14 | path := make([]string, 0, len(Suffix)+1) 15 | path = append(path, Suffix...) 16 | resp, err := c.Communicate("POST", path, nil, req, nil) 17 | if err != nil { 18 | return err 19 | } 20 | file, err := os.OpenFile(filename, os.O_TRUNC|os.O_CREATE|os.O_RDWR, 0777) 21 | if err != nil { 22 | return fmt.Errorf("Invalid path: %s", filename) 23 | } 24 | 25 | _, err = file.Write(resp) 26 | if err != nil { 27 | return err 28 | } 29 | file.Close() 30 | return err 31 | 32 | } 33 | -------------------------------------------------------------------------------- /cloud/account-v2/gcpTemplate/structs.go: -------------------------------------------------------------------------------- 1 | package gcpTemplate 2 | 3 | type GcpTemplateReq struct { 4 | ProjectId string `json:"projectId"` 5 | OrgId string `json:"orgId"` 6 | AccountType string `json:"accountType"` 7 | AuthenticationType string `json:"authenticationType"` 8 | Name string `json:"name"` 9 | Features []string `json:"features"` 10 | FileName string `json:"fileName"` 11 | FlowLogStorageBucket string `json:"flowLogStorageBucket"` 12 | } 13 | 14 | type GcpTemplate struct { 15 | ProjectId string `json:"projectId"` 16 | OrgId string `json:"orgId"` 17 | AccountType string `json:"accountType"` 18 | AuthenticationType string `json:"authenticationType"` 19 | Name string `json:"name"` 20 | Features []string `json:"features"` 21 | FileName string `json:"fileName"` 22 | FlowLogStorageBucket string `json:"flowLogStorageBucket"` 23 | } 24 | -------------------------------------------------------------------------------- /cloud/account-v2/ibmTemplate/const.go: -------------------------------------------------------------------------------- 1 | package ibmTemplate 2 | 3 | var Suffix = []string{"cas/v1/ibm_template"} 4 | -------------------------------------------------------------------------------- /cloud/account-v2/ibmTemplate/funcs.go: -------------------------------------------------------------------------------- 1 | package ibmTemplate 2 | 3 | import ( 4 | "fmt" 5 | pc "github.com/paloaltonetworks/prisma-cloud-go" 6 | "os" 7 | ) 8 | 9 | func GetIbmTemplate(c pc.PrismaCloudClient, req IbmTemplateReq) error { 10 | 11 | filename := req.FileName 12 | filename = filename + ".tf.json" 13 | 14 | path := make([]string, 0, len(Suffix)+1) 15 | path = append(path, Suffix...) 16 | resp, err := c.Communicate("POST", path, nil, req, nil) 17 | if err != nil { 18 | return err 19 | } 20 | file, err := os.OpenFile(filename, os.O_TRUNC|os.O_CREATE|os.O_RDWR, 0777) 21 | if err != nil { 22 | return fmt.Errorf("Invalid path: %s", filename) 23 | } 24 | 25 | _, err = file.Write(resp) 26 | if err != nil { 27 | return err 28 | } 29 | file.Close() 30 | return err 31 | 32 | } 33 | -------------------------------------------------------------------------------- /cloud/account-v2/ibmTemplate/structs.go: -------------------------------------------------------------------------------- 1 | package ibmTemplate 2 | 3 | type IbmTemplateReq struct { 4 | AccountType string `json:"accountType"` 5 | FileName string `json:"fileName"` 6 | } 7 | 8 | type IbmTemplate struct { 9 | AccountType string `json:"accountType"` 10 | FileName string `json:"fileName"` 11 | } 12 | -------------------------------------------------------------------------------- /cloud/account-v2/org/const.go: -------------------------------------------------------------------------------- 1 | package org 2 | 3 | const ( 4 | singular = "org cloud account" 5 | plural = "org cloud accounts" 6 | ) 7 | 8 | var DeleteSuffix = []string{"cloud"} 9 | 10 | var Suffix = []string{"cas", "v1"} 11 | 12 | var ListSuffix = []string{"v1", "cloudAccounts"} 13 | 14 | var ListSuffixAws = []string{"v1", "cloudAccounts", "awsAccounts"} 15 | 16 | var ListSuffixAzure = []string{"v1", "cloudAccounts", "azureAccounts"} 17 | 18 | var ListSuffixGcp = []string{"cas", "v1", "cloud_account", "gcp"} 19 | 20 | const ( 21 | TypeAwsOrg = "aws" 22 | TypeAzureOrg = "azure" 23 | TypeGcpOrg = "gcp" 24 | ) 25 | -------------------------------------------------------------------------------- /cloud/account-v2/org/funcs.go: -------------------------------------------------------------------------------- 1 | package org 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | pc "github.com/paloaltonetworks/prisma-cloud-go" 8 | ) 9 | 10 | // List lists all cloud accounts onboarded onto the Prisma Cloud platform. 11 | func List(c pc.PrismaCloudClient) ([]AccountResponse, error) { 12 | c.Log(pc.LogAction, "(get) list of %s", plural) 13 | 14 | var ans []AccountResponse 15 | if _, err := c.Communicate("GET", ListSuffixAws, nil, nil, &ans); err != nil { 16 | return nil, err 17 | } 18 | 19 | return ans, nil 20 | } 21 | 22 | func ListAzure(c pc.PrismaCloudClient) ([]AzureAccountResponse, error) { 23 | c.Log(pc.LogAction, "(get) list of %s", plural) 24 | 25 | var ansaz []AzureAccountResponse 26 | if _, err := c.Communicate("GET", ListSuffixAzure, nil, nil, &ansaz); err != nil { 27 | return nil, err 28 | } 29 | 30 | return ansaz, nil 31 | } 32 | 33 | func ListGcp(c pc.PrismaCloudClient) ([]GcpAccountResponse, error) { 34 | c.Log(pc.LogAction, "(get) list of %s", plural) 35 | 36 | var ansgcp []GcpAccountResponse 37 | path := make([]string, 0, len(ListSuffix)+1) 38 | path = append(path, ListSuffix...) 39 | path = append(path, "accounts?cloudTypes=gcp") 40 | if _, err := c.Communicate("GET", path, nil, nil, &ansgcp); err != nil { 41 | return nil, err 42 | } 43 | return ansgcp, nil 44 | } 45 | 46 | // Names returns the name listing for cloud accounts. 47 | func Names(c pc.PrismaCloudClient) ([]NameTypeId, error) { 48 | c.Log(pc.LogAction, "(get) %s names", singular) 49 | 50 | path := make([]string, 0, len(Suffix)+1) 51 | path = append(path, Suffix...) 52 | path = append(path, "name") 53 | 54 | var ans []NameTypeId 55 | _, err := c.Communicate("GET", path, nil, nil, &ans) 56 | 57 | return ans, err 58 | } 59 | 60 | // Identify returns the ID for the given cloud type and name. 61 | func Identify(c pc.PrismaCloudClient, cloudType, name string) (string, error) { 62 | c.Log(pc.LogAction, "(get) id for %s type:%s name:%s", singular, cloudType, name) 63 | if cloudType == "aws" { 64 | ans, err := List(c) 65 | if err != nil { 66 | return "", err 67 | } 68 | 69 | for _, o := range ans { 70 | if strings.EqualFold(o.CloudAccountResp.CloudType, cloudType) && o.CloudAccountResp.Name == name { 71 | return o.CloudAccountResp.AccountId, nil 72 | } 73 | 74 | } 75 | } 76 | if strings.EqualFold("azure", cloudType) { 77 | ansaz, err := ListAzure(c) 78 | if err != nil { 79 | return "", err 80 | } 81 | 82 | for _, o := range ansaz { 83 | if strings.EqualFold(o.CloudAccountAzureResp.CloudType, cloudType) && o.CloudAccountAzureResp.Name == name { 84 | return o.CloudAccountAzureResp.AccountId, nil 85 | } 86 | 87 | } 88 | } 89 | if strings.EqualFold("gcp", cloudType) { 90 | ansgcp, err := ListGcp(c) 91 | if err != nil { 92 | return "", err 93 | } 94 | 95 | for _, o := range ansgcp { 96 | if strings.EqualFold(o.CloudType, cloudType) && o.Name == name { 97 | return o.AccountId, nil 98 | } 99 | 100 | } 101 | } 102 | 103 | return "", pc.ObjectNotFoundError 104 | } 105 | 106 | func Get(c pc.PrismaCloudClient, cloudType, id string) (interface{}, error) { 107 | var cloud string 108 | cloud = cloudType 109 | cloud = cloud + "Accounts" 110 | c.Log(pc.LogAction, "(get) %s type:%s id:%s", singular, cloudType, id) 111 | 112 | if cloudType == "gcp" { 113 | path := make([]string, 0, len(ListSuffixGcp)+1) 114 | path = append(path, ListSuffixGcp...) 115 | path = append(path, id) 116 | 117 | var ans interface{} 118 | 119 | switch cloudType { 120 | case TypeGcpOrg: 121 | ans = &GcpOrgV2{} 122 | default: 123 | return nil, fmt.Errorf("Invalid cloud type: %s", cloudType) 124 | } 125 | _, err := c.Communicate("GET", path, nil, nil, ans) 126 | 127 | switch cloudType { 128 | case TypeGcpOrg: 129 | return *ans.(*GcpOrgV2), err 130 | } 131 | } else { 132 | path := make([]string, 0, len(ListSuffix)+1) 133 | path = append(path, ListSuffix...) 134 | path = append(path, cloud, id) 135 | var ans interface{} 136 | 137 | switch cloudType { 138 | case TypeAwsOrg: 139 | ans = &AwsOrgV2{} 140 | case TypeAzureOrg: 141 | ans = &AzureOrgV2{} 142 | default: 143 | return nil, fmt.Errorf("Invalid cloud type: %s", cloudType) 144 | } 145 | _, err := c.Communicate("GET", path, nil, nil, ans) 146 | 147 | switch cloudType { 148 | case TypeAwsOrg: 149 | return *ans.(*AwsOrgV2), err 150 | case TypeAzureOrg: 151 | return *ans.(*AzureOrgV2), err 152 | } 153 | 154 | } 155 | return nil, fmt.Errorf("Invalid cloud type: %s", cloudType) 156 | } 157 | 158 | // Create onboards a new cloud account onto the Prisma Cloud platform. 159 | func Create(c pc.PrismaCloudClient, account interface{}) error { 160 | return createUpdate(false, c, account) 161 | } 162 | 163 | // Update modifies information related to a cloud account. 164 | func Update(c pc.PrismaCloudClient, account interface{}) error { 165 | return createUpdate(true, c, account) 166 | } 167 | 168 | // Delete removes an onboarded cloud account using the cloud account ID. 169 | func Delete(c pc.PrismaCloudClient, cloudType, id string) error { 170 | c.Log(pc.LogAction, "(delete) %s type:%s id:%s", singular, cloudType, id) 171 | 172 | path := make([]string, 0, len(DeleteSuffix)+2) 173 | path = append(path, DeleteSuffix...) 174 | path = append(path, cloudType, id) 175 | _, err := c.Communicate("DELETE", path, nil, nil, nil) 176 | return err 177 | } 178 | 179 | func DisableCloudAccount(c pc.PrismaCloudClient, accountId string) error { 180 | var ( 181 | method string 182 | ) 183 | method = "PATCH" 184 | 185 | path := make([]string, 0, len(Suffix)+1) 186 | path = append(path, "cloud") 187 | path = append(path, accountId) 188 | path = append(path, "status") 189 | path = append(path, "false") 190 | 191 | _, err := c.Communicate(method, path, nil, nil, nil) 192 | return err 193 | } 194 | 195 | func createUpdate(exists bool, c pc.PrismaCloudClient, account interface{}) error { 196 | var ( 197 | logMsg strings.Builder 198 | id string 199 | method string 200 | cloudType string 201 | ) 202 | 203 | logMsg.Grow(30) 204 | logMsg.WriteString("(") 205 | if exists { 206 | logMsg.WriteString("update") 207 | method = "PUT" 208 | } else { 209 | logMsg.WriteString("create") 210 | method = "POST" 211 | } 212 | logMsg.WriteString(") ") 213 | 214 | switch v := account.(type) { 215 | case nil: 216 | return fmt.Errorf("Cloud account specified") 217 | case AwsOrg: 218 | logMsg.WriteString("aws") 219 | cloudType = TypeAwsOrg 220 | id = v.AccountId 221 | case AzureOrg: 222 | logMsg.WriteString("azure") 223 | cloudType = TypeAzureOrg 224 | id = v.TenantId 225 | case GcpOrg: 226 | logMsg.WriteString("gcp") 227 | cloudType = TypeGcpOrg 228 | id = v.OrgAccountGcp.AccountId 229 | default: 230 | return fmt.Errorf("invalid account type %v", v) 231 | } 232 | 233 | logMsg.WriteString(" ") 234 | logMsg.WriteString(singular) 235 | if exists { 236 | fmt.Fprintf(&logMsg, ": %s", id) 237 | } 238 | 239 | c.Log(pc.LogAction, logMsg.String()) 240 | 241 | path := make([]string, 0, len(Suffix)+1) 242 | path = append(path, Suffix...) 243 | cloudType = cloudType + "_account" 244 | path = append(path, cloudType) 245 | if exists { 246 | path = append(path, id) 247 | } 248 | _, err := c.Communicate(method, path, nil, account, nil) 249 | return err 250 | } 251 | -------------------------------------------------------------------------------- /cloud/account-v2/supportedFeatures/const.go: -------------------------------------------------------------------------------- 1 | package supportedFeatures 2 | 3 | var Suffix = []string{"cas/v1/features/cloud"} 4 | -------------------------------------------------------------------------------- /cloud/account-v2/supportedFeatures/funcs.go: -------------------------------------------------------------------------------- 1 | package supportedFeatures 2 | 3 | import ( 4 | pc "github.com/paloaltonetworks/prisma-cloud-go" 5 | ) 6 | 7 | func GetSupportedFeatures(c pc.PrismaCloudClient, req SupportedFeaturesReq) (SupportedFeatures, error) { 8 | c.Log(pc.LogAction, "(post) performing fetch supported features") 9 | 10 | var resp SupportedFeatures 11 | path := make([]string, 0, len(Suffix)+2) 12 | path = append(path, Suffix...) 13 | path = append(path, req.CloudType) 14 | _, err := c.Communicate("POST", path, nil, req, &resp) 15 | return resp, err 16 | } 17 | -------------------------------------------------------------------------------- /cloud/account-v2/supportedFeatures/structs.go: -------------------------------------------------------------------------------- 1 | package supportedFeatures 2 | 3 | type SupportedFeaturesReq struct { 4 | CloudType string `json:"cloudType"` 5 | AccountType string `json:"accountType"` 6 | DeploymentType string `json:"deploymentType"` 7 | AwsPartition string `json:"awsPartition"` 8 | RootSyncEnabled bool `json:"rootSyncEnabled"` 9 | } 10 | 11 | type SupportedFeatures struct { 12 | AccountType string `json:"accountType"` 13 | DeploymentType string `json:"deploymentType"` 14 | AwsPartition string `json:"awsPartition"` 15 | RootSyncEnabled bool `json:"rootSyncEnabled"` 16 | CloudType string `json:"cloudType"` 17 | LicenseType string `json:"licenseType"` 18 | SupportedFeatures []string `json:"supportedFeatures"` 19 | } 20 | -------------------------------------------------------------------------------- /cloud/account/const.go: -------------------------------------------------------------------------------- 1 | package account 2 | 3 | const ( 4 | singular = "cloud account" 5 | plural = "cloud accounts" 6 | ) 7 | 8 | var Suffix = []string{"cloud"} 9 | 10 | const ( 11 | TypeAws = "aws" 12 | TypeAzure = "azure" 13 | TypeGcp = "gcp" 14 | TypeAlibaba = "alibaba_cloud" 15 | ) 16 | -------------------------------------------------------------------------------- /cloud/account/funcs.go: -------------------------------------------------------------------------------- 1 | package account 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | pc "github.com/paloaltonetworks/prisma-cloud-go" 8 | ) 9 | 10 | // List lists all cloud accounts onboarded onto the Prisma Cloud platform. 11 | func List(c pc.PrismaCloudClient) ([]Account, error) { 12 | c.Log(pc.LogAction, "(get) list of %s", plural) 13 | 14 | var ans []Account 15 | if _, err := c.Communicate("GET", Suffix, nil, nil, &ans); err != nil { 16 | return nil, err 17 | } 18 | 19 | return ans, nil 20 | } 21 | 22 | // Names returns the name listing for cloud accounts. 23 | func Names(c pc.PrismaCloudClient) ([]NameTypeId, error) { 24 | c.Log(pc.LogAction, "(get) %s names", singular) 25 | 26 | path := make([]string, 0, len(Suffix)+1) 27 | path = append(path, Suffix...) 28 | path = append(path, "name") 29 | 30 | var ans []NameTypeId 31 | _, err := c.Communicate("GET", path, nil, nil, &ans) 32 | 33 | return ans, err 34 | } 35 | 36 | // Identify returns the ID for the given cloud type and name. 37 | func Identify(c pc.PrismaCloudClient, cloudType, name string) (string, error) { 38 | c.Log(pc.LogAction, "(get) id for %s type:%s name:%s", singular, cloudType, name) 39 | 40 | ans, err := Names(c) 41 | if err != nil { 42 | return "", err 43 | } 44 | 45 | for _, o := range ans { 46 | if o.CloudType == cloudType && o.Name == name { 47 | return o.AccountId, nil 48 | } 49 | } 50 | 51 | return "", pc.ObjectNotFoundError 52 | } 53 | 54 | /* 55 | Get returns top level information about the cloud account. 56 | 57 | The interface returned will be one of the following: 58 | - account.Aws 59 | - account.Azure 60 | - account.Gcp 61 | - account.Alibaba 62 | - nil 63 | */ 64 | func Get(c pc.PrismaCloudClient, cloudType, id string) (interface{}, error) { 65 | c.Log(pc.LogAction, "(get) %s type:%s id:%s", singular, cloudType, id) 66 | 67 | path := make([]string, 0, len(Suffix)+2) 68 | path = append(path, Suffix...) 69 | path = append(path, cloudType, id) 70 | 71 | var ans interface{} 72 | 73 | switch cloudType { 74 | case TypeAws: 75 | ans = &Aws{} 76 | case TypeAzure: 77 | ans = &Azure{} 78 | case TypeGcp: 79 | ans = &Gcp{} 80 | case TypeAlibaba: 81 | ans = &Alibaba{} 82 | default: 83 | return nil, fmt.Errorf("Invalid cloud type: %s", cloudType) 84 | } 85 | 86 | _, err := c.Communicate("GET", path, nil, nil, ans) 87 | 88 | // Can't just return ans here or it won't be right, so re-cast it back 89 | // to the appropriate specific object type. 90 | switch cloudType { 91 | case TypeAws: 92 | return *ans.(*Aws), err 93 | case TypeAzure: 94 | return *ans.(*Azure), err 95 | case TypeGcp: 96 | return *ans.(*Gcp), err 97 | case TypeAlibaba: 98 | return *ans.(*Alibaba), err 99 | } 100 | 101 | return nil, fmt.Errorf("Invalid cloud type: %s", cloudType) 102 | } 103 | 104 | // Create onboards a new cloud account onto the Prisma Cloud platform. 105 | func Create(c pc.PrismaCloudClient, account interface{}) error { 106 | return createUpdate(false, c, account) 107 | } 108 | 109 | // Update modifies information related to a cloud account. 110 | func Update(c pc.PrismaCloudClient, account interface{}) error { 111 | return createUpdate(true, c, account) 112 | } 113 | 114 | // Delete removes an onboarded cloud account using the cloud account ID. 115 | func Delete(c pc.PrismaCloudClient, cloudType, id string) error { 116 | c.Log(pc.LogAction, "(delete) %s type:%s id:%s", singular, cloudType, id) 117 | 118 | //path := strings.Join([]string{Suffix, cloudType, id}, "/") 119 | path := make([]string, 0, len(Suffix)+2) 120 | path = append(path, Suffix...) 121 | path = append(path, cloudType, id) 122 | _, err := c.Communicate("DELETE", path, nil, nil, nil) 123 | return err 124 | } 125 | 126 | func createUpdate(exists bool, c pc.PrismaCloudClient, account interface{}) error { 127 | var ( 128 | cloudType string 129 | logMsg strings.Builder 130 | id string 131 | method string 132 | ) 133 | 134 | logMsg.Grow(30) 135 | logMsg.WriteString("(") 136 | if exists { 137 | logMsg.WriteString("update") 138 | method = "PUT" 139 | } else { 140 | logMsg.WriteString("create") 141 | method = "POST" 142 | } 143 | logMsg.WriteString(") ") 144 | 145 | switch v := account.(type) { 146 | case nil: 147 | return fmt.Errorf("Cloud account specified") 148 | case Aws: 149 | logMsg.WriteString("aws") 150 | cloudType = TypeAws 151 | id = v.AccountId 152 | case Azure: 153 | logMsg.WriteString("azure") 154 | cloudType = TypeAzure 155 | id = v.Account.AccountId 156 | case Gcp: 157 | logMsg.WriteString("gcp") 158 | cloudType = TypeGcp 159 | id = v.Account.AccountId 160 | case Alibaba: 161 | logMsg.WriteString("alibaba") 162 | cloudType = TypeAlibaba 163 | id = v.AccountId 164 | default: 165 | return fmt.Errorf("invalid account type %v", v) 166 | } 167 | 168 | logMsg.WriteString(" ") 169 | logMsg.WriteString(singular) 170 | if exists { 171 | fmt.Fprintf(&logMsg, ": %s", id) 172 | } 173 | 174 | c.Log(pc.LogAction, logMsg.String()) 175 | 176 | path := make([]string, 0, len(Suffix)+2) 177 | path = append(path, Suffix...) 178 | path = append(path, cloudType) 179 | if exists { 180 | path = append(path, id) 181 | } 182 | 183 | //method, path, queryparams, request, responseObj, 184 | _, err := c.Communicate(method, path, nil, account, nil) 185 | return err 186 | } 187 | -------------------------------------------------------------------------------- /cloud/account/group/const.go: -------------------------------------------------------------------------------- 1 | package group 2 | 3 | const ( 4 | singular = "cloud account group" 5 | plural = "cloud account groups" 6 | ) 7 | 8 | var Suffix = []string{"cloud", "group"} 9 | -------------------------------------------------------------------------------- /cloud/account/group/funcs.go: -------------------------------------------------------------------------------- 1 | package group 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | pc "github.com/paloaltonetworks/prisma-cloud-go" 8 | ) 9 | 10 | // List lists accessible account groups. 11 | func List(c pc.PrismaCloudClient) ([]Group, error) { 12 | c.Log(pc.LogAction, "(get) list of %s", plural) 13 | 14 | var ans []Group 15 | if _, err := c.Communicate("GET", Suffix, nil, nil, &ans); err != nil { 16 | return nil, err 17 | } 18 | 19 | return ans, nil 20 | } 21 | 22 | // Identify returns the ID for the given account group. 23 | func Identify(c pc.PrismaCloudClient, name string) (string, error) { 24 | c.Log(pc.LogAction, "(get) id for %s: %s", singular, name) 25 | 26 | path := make([]string, 0, len(Suffix)+1) 27 | path = append(path, Suffix...) 28 | path = append(path, "name") 29 | 30 | var ans []NameId 31 | if _, err := c.Communicate("GET", path, nil, nil, &ans); err != nil { 32 | return "", err 33 | } 34 | 35 | for _, o := range ans { 36 | if o.Name == name { 37 | return o.Id, nil 38 | } 39 | } 40 | 41 | return "", pc.ObjectNotFoundError 42 | } 43 | 44 | // Get returns all information about an account group using its ID. 45 | func Get(c pc.PrismaCloudClient, id string) (Group, error) { 46 | c.Log(pc.LogAction, "(get) %s: %s", singular, id) 47 | 48 | var ans Group 49 | path := make([]string, 0, len(Suffix)+1) 50 | path = append(path, Suffix...) 51 | path = append(path, id) 52 | 53 | _, err := c.Communicate("GET", path, nil, nil, &ans) 54 | return ans, err 55 | } 56 | 57 | // Create makes a new account group on the Prisma Cloud platform. 58 | func Create(c pc.PrismaCloudClient, group Group) error { 59 | return createUpdate(false, c, group) 60 | } 61 | 62 | // UpdateUsingLiveAccountIds copies the AccountIds param from what's 63 | // live, but otherwise with the group definition provided. The problem is 64 | // that the API endpoint can change the accounts associated with this group, 65 | // but in Terraform the group membership is a read-only attribute. 66 | func UpdateUsingLiveAccountIds(c pc.PrismaCloudClient, group Group) error { 67 | lg, err := Get(c, group.Id) 68 | if err != nil { 69 | return err 70 | } 71 | group.AccountIds = lg.AccountIds 72 | 73 | return Update(c, group) 74 | } 75 | 76 | // Update modifies information related to an existing account group. 77 | func Update(c pc.PrismaCloudClient, group Group) error { 78 | return createUpdate(true, c, group) 79 | } 80 | 81 | // Delete removes an existing account group using its ID. 82 | func Delete(c pc.PrismaCloudClient, id string) error { 83 | c.Log(pc.LogAction, "(delete) %s: %s", singular, id) 84 | 85 | path := make([]string, 0, len(Suffix)+1) 86 | path = append(path, Suffix...) 87 | path = append(path, id) 88 | 89 | _, err := c.Communicate("DELETE", path, nil, nil, nil) 90 | return err 91 | } 92 | 93 | func createUpdate(exists bool, c pc.PrismaCloudClient, group Group) error { 94 | var ( 95 | logMsg strings.Builder 96 | method string 97 | ) 98 | 99 | logMsg.Grow(30) 100 | logMsg.WriteString("(") 101 | if exists { 102 | logMsg.WriteString("update") 103 | method = "PUT" 104 | } else { 105 | logMsg.WriteString("create") 106 | method = "POST" 107 | } 108 | logMsg.WriteString(") ") 109 | 110 | logMsg.WriteString(singular) 111 | if exists { 112 | fmt.Fprintf(&logMsg, ": %s", group.Id) 113 | } 114 | 115 | c.Log(pc.LogAction, logMsg.String()) 116 | 117 | path := make([]string, 0, len(Suffix)+1) 118 | path = append(path, Suffix...) 119 | if exists { 120 | path = append(path, group.Id) 121 | } 122 | 123 | _, err := c.Communicate(method, path, nil, group, nil) 124 | return err 125 | } 126 | -------------------------------------------------------------------------------- /cloud/account/group/structs.go: -------------------------------------------------------------------------------- 1 | package group 2 | 3 | type NameId struct { 4 | Name string `json:"name"` 5 | Id string `json:"id"` 6 | } 7 | 8 | type Group struct { 9 | Id string `json:"id,omitempty"` 10 | Name string `json:"name"` 11 | Description string `json:"description"` 12 | LastModifiedBy string `json:"lastModifiedBy"` 13 | LastModifiedTs int64 `json:"lastModifiedTs"` 14 | AccountIds []string `json:"accountIds"` 15 | Accounts []Account `json:"accounts,omitempty"` 16 | AlertRules []AlertRule `json:"alertRules,omitempty"` 17 | ChildGroupIds []string `json:"childGroupIds"` 18 | ParentInfo ParentInfo `json:"parentInfo,omitempty"` 19 | } 20 | 21 | type Account struct { 22 | Id string `json:"id"` 23 | Name string `json:"name"` 24 | Type string `json:"type"` 25 | } 26 | 27 | type AlertRule struct { 28 | Id string `json:"alertId"` 29 | Name string `json:"alertName"` 30 | } 31 | 32 | type ParentInfo struct { 33 | Id string `json:"id"` 34 | Name string `json:"name"` 35 | AutoCreated bool `json:"autoCreated"` 36 | } 37 | -------------------------------------------------------------------------------- /cloud/account/org/const.go: -------------------------------------------------------------------------------- 1 | package org 2 | 3 | const ( 4 | singular = "org cloud account" 5 | plural = "org cloud accounts" 6 | ) 7 | 8 | var Suffix = []string{"cloud"} 9 | 10 | const ( 11 | TypeAwsOrg = "aws" 12 | TypeAzureOrg = "azure" 13 | TypeGcpOrg = "gcp" 14 | TypeOci = "oci" 15 | ) 16 | -------------------------------------------------------------------------------- /cloud/account/org/funcs.go: -------------------------------------------------------------------------------- 1 | package org 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | pc "github.com/paloaltonetworks/prisma-cloud-go" 8 | ) 9 | 10 | // List lists all cloud accounts onboarded onto the Prisma Cloud platform. 11 | func List(c pc.PrismaCloudClient) ([]OrgAccount, error) { 12 | c.Log(pc.LogAction, "(get) list of %s", plural) 13 | 14 | var ans []OrgAccount 15 | if _, err := c.Communicate("GET", Suffix, nil, nil, &ans); err != nil { 16 | return nil, err 17 | } 18 | 19 | return ans, nil 20 | } 21 | 22 | // Names returns the name listing for cloud accounts. 23 | func Names(c pc.PrismaCloudClient) ([]NameTypeId, error) { 24 | c.Log(pc.LogAction, "(get) %s names", singular) 25 | 26 | path := make([]string, 0, len(Suffix)+1) 27 | path = append(path, Suffix...) 28 | path = append(path, "name") 29 | 30 | var ans []NameTypeId 31 | _, err := c.Communicate("GET", path, nil, nil, &ans) 32 | 33 | return ans, err 34 | } 35 | 36 | // Identify returns the ID for the given cloud type and name. 37 | func Identify(c pc.PrismaCloudClient, cloudType, name string) (string, error) { 38 | c.Log(pc.LogAction, "(get) id for %s type:%s name:%s", singular, cloudType, name) 39 | 40 | ans, err := Names(c) 41 | if err != nil { 42 | return "", err 43 | } 44 | 45 | for _, o := range ans { 46 | if o.CloudType == cloudType && o.Name == name { 47 | return o.AccountId, nil 48 | } 49 | } 50 | 51 | return "", pc.ObjectNotFoundError 52 | } 53 | 54 | /* 55 | Get returns top level information about the cloud account. 56 | 57 | The interface returned will be one of the following: 58 | - account.Aws 59 | - account.Azure 60 | - account.Gcp 61 | - account.Alibaba 62 | - nil 63 | */ 64 | func Get(c pc.PrismaCloudClient, cloudType, id string) (interface{}, error) { 65 | c.Log(pc.LogAction, "(get) %s type:%s id:%s", singular, cloudType, id) 66 | 67 | path := make([]string, 0, len(Suffix)+2) 68 | path = append(path, Suffix...) 69 | path = append(path, cloudType, id) 70 | 71 | var ans interface{} 72 | 73 | switch cloudType { 74 | case TypeAwsOrg: 75 | ans = &AwsOrg{} 76 | case TypeAzureOrg: 77 | ans = &AzureOrg{} 78 | case TypeGcpOrg: 79 | ans = &GcpOrg{} 80 | case TypeOci: 81 | ans = &Oci{} 82 | default: 83 | return nil, fmt.Errorf("Invalid cloud type: %s", cloudType) 84 | } 85 | 86 | _, err := c.Communicate("GET", path, nil, nil, ans) 87 | 88 | // Can't just return ans here or it won't be right, so re-cast it back 89 | // to the appropriate specific object type. 90 | switch cloudType { 91 | case TypeAwsOrg: 92 | return *ans.(*AwsOrg), err 93 | case TypeAzureOrg: 94 | return *ans.(*AzureOrg), err 95 | case TypeGcpOrg: 96 | return *ans.(*GcpOrg), err 97 | case TypeOci: 98 | return *ans.(*Oci), err 99 | } 100 | 101 | return nil, fmt.Errorf("Invalid cloud type: %s", cloudType) 102 | } 103 | 104 | // Create onboards a new cloud account onto the Prisma Cloud platform. 105 | func Create(c pc.PrismaCloudClient, account interface{}) error { 106 | return createUpdate(false, c, account) 107 | } 108 | 109 | // Update modifies information related to a cloud account. 110 | func Update(c pc.PrismaCloudClient, account interface{}) error { 111 | return createUpdate(true, c, account) 112 | } 113 | 114 | // Delete removes an onboarded cloud account using the cloud account ID. 115 | func Delete(c pc.PrismaCloudClient, cloudType, id string) error { 116 | c.Log(pc.LogAction, "(delete) %s type:%s id:%s", singular, cloudType, id) 117 | 118 | //path := strings.Join([]string{Suffix, cloudType, id}, "/") 119 | path := make([]string, 0, len(Suffix)+2) 120 | path = append(path, Suffix...) 121 | path = append(path, cloudType, id) 122 | _, err := c.Communicate("DELETE", path, nil, nil, nil) 123 | return err 124 | } 125 | 126 | func createUpdate(exists bool, c pc.PrismaCloudClient, account interface{}) error { 127 | var ( 128 | cloudType string 129 | logMsg strings.Builder 130 | id string 131 | method string 132 | ) 133 | 134 | logMsg.Grow(30) 135 | logMsg.WriteString("(") 136 | if exists { 137 | logMsg.WriteString("update") 138 | method = "PUT" 139 | } else { 140 | logMsg.WriteString("create") 141 | method = "POST" 142 | } 143 | logMsg.WriteString(") ") 144 | 145 | switch v := account.(type) { 146 | case nil: 147 | return fmt.Errorf("Cloud account specified") 148 | case AwsOrg: 149 | logMsg.WriteString("aws") 150 | cloudType = TypeAwsOrg 151 | id = v.AccountId 152 | case AzureOrg: 153 | logMsg.WriteString("azure") 154 | cloudType = TypeAzureOrg 155 | id = v.Account.AccountId 156 | case GcpOrg: 157 | logMsg.WriteString("gcp") 158 | cloudType = TypeGcpOrg 159 | id = v.Account.AccountId 160 | case Oci: 161 | logMsg.WriteString("oci") 162 | cloudType = TypeOci 163 | id = v.AccountId 164 | default: 165 | return fmt.Errorf("invalid account type %v", v) 166 | } 167 | 168 | logMsg.WriteString(" ") 169 | logMsg.WriteString(singular) 170 | if exists { 171 | fmt.Fprintf(&logMsg, ": %s", id) 172 | } 173 | 174 | c.Log(pc.LogAction, logMsg.String()) 175 | 176 | path := make([]string, 0, len(Suffix)+2) 177 | path = append(path, Suffix...) 178 | path = append(path, cloudType) 179 | if exists { 180 | path = append(path, id) 181 | } 182 | 183 | _, err := c.Communicate(method, path, nil, account, nil) 184 | return err 185 | } 186 | -------------------------------------------------------------------------------- /cloud/account/org/structs.go: -------------------------------------------------------------------------------- 1 | package org 2 | 3 | type AccountAndCredentials struct { 4 | Account OrgAccount `json:"cloudAccount"` 5 | } 6 | 7 | type NameTypeId struct { 8 | Name string `json:"name"` 9 | CloudType string `json:"cloudType"` 10 | AccountId string `json:"id"` 11 | } 12 | 13 | type OrgAccount struct { 14 | Name string `json:"name"` 15 | CloudType string `json:"cloudType"` 16 | AccountType string `json:"accountType"` 17 | Enabled bool `json:"enabled"` 18 | LastModifiedTs int `json:"lastModifiedTs"` 19 | LastModifiedBy string `json:"lastModifiedBy"` 20 | StorageScanEnabled bool `json:"storageScanEnabled"` 21 | ProtectionMode string `json:"protectionMode"` 22 | IngestionMode int `json:"ingestionMode"` 23 | GroupIds []string `json:"groupIds"` 24 | Groups []Group `json:"groups"` 25 | Status string `json:"status"` 26 | NumberOfChildAccounts int `json:"numberOfChildAccounts"` 27 | AccountId string `json:"accountId,omitempty"` 28 | AddedOn int `json:"addedOn"` 29 | } 30 | 31 | type Group struct { 32 | Id string `json:"id"` 33 | Name string `json:"name"` 34 | } 35 | 36 | type AwsOrg struct { 37 | AccountId string `json:"accountId"` 38 | Enabled bool `json:"enabled"` 39 | ExternalId string `json:"externalId"` 40 | GroupIds []string `json:"groupIds"` 41 | Name string `json:"name"` 42 | RoleArn string `json:"roleArn"` 43 | ProtectionMode string `json:"protectionMode"` 44 | AccountType string `json:"accountType"` 45 | MemberRoleName string `json:"memberRoleName"` 46 | MemberExternalId string `json:"memberExternalId"` 47 | MemberRoleStatus bool `json:"memberRoleStatus"` 48 | HierarchySelection []HierarchySelection `json:"hierarchySelection"` 49 | } 50 | 51 | type GcpCloudAccount struct { 52 | AccountId string `json:"accountId"` 53 | Enabled bool `json:"enabled"` 54 | ProjectId string `json:"projectId"` 55 | GroupIds []string `json:"groupIds"` 56 | Name string `json:"name"` 57 | ProtectionMode string `json:"protectionMode"` 58 | AccountType string `json:"accountType"` 59 | } 60 | 61 | type AzureCloudAccount struct { 62 | AccountId string `json:"accountId"` 63 | Enabled bool `json:"enabled"` 64 | GroupIds []string `json:"groupIds"` 65 | Name string `json:"name"` 66 | ProtectionMode string `json:"protectionMode"` 67 | AccountType string `json:"accountType"` 68 | } 69 | 70 | type AzureOrg struct { 71 | Account AzureCloudAccount `json:"cloudAccount"` 72 | ClientId string `json:"clientId"` 73 | Key string `json:"key"` 74 | MonitorFlowLogs bool `json:"monitorFlowLogs"` 75 | TenantId string `json:"tenantId"` 76 | ServicePrincipalId string `json:"servicePrincipalId"` 77 | RootSyncEnabled bool `json:"rootSyncEnabled"` 78 | HierarchySelection []HierarchySelection `json:"hierarchySelection"` 79 | } 80 | 81 | type GcpOrgCredentials struct { 82 | Type string `json:"type"` 83 | ProjectId string `json:"project_id"` 84 | PrivateKeyId string `json:"private_key_id"` 85 | PrivateKey string `json:"private_key"` 86 | ClientEmail string `json:"client_email"` 87 | ClientId string `json:"client_id"` 88 | AuthUri string `json:"auth_uri"` 89 | TokenUri string `json:"token_uri"` 90 | ProviderCertUrl string `json:"auth_provider_x509_cert_url"` 91 | ClientCertUrl string `json:"client_x509_cert_url"` 92 | Audience string `json:"audience"` 93 | SubjectTokenType string `json:"subject_token_type"` 94 | ServiceAccountImpersonationUrl string `json:"service_account_impersonation_url"` 95 | CredentialSource CredentialSource `json:"credential_source"` 96 | TokenUrl string `json:"token_url"` 97 | } 98 | 99 | type CredentialSource struct { 100 | EnvironmentId string `json:"environment_id"` 101 | RegionUrl string `json:"region_url"` 102 | Url string `json:"url"` 103 | RegionalCredVerificationUrl string `json:"regional_cred_verification_url"` 104 | } 105 | 106 | type HierarchySelection struct { 107 | ResourceId string `json:"resourceId"` 108 | DisplayName string `json:"displayName"` 109 | NodeType string `json:"nodeType"` 110 | SelectionType string `json:"selectionType"` 111 | } 112 | 113 | type GcpOrg struct { 114 | Account GcpCloudAccount `json:"cloudAccount"` 115 | CompressionEnabled bool `json:"compressionEnabled"` 116 | DataflowEnabledProject string `json:"dataflowEnabledProject"` 117 | FlowLogStorageBucket string `json:"flowLogStorageBucket"` 118 | OrganizationName string `json:"organizationName"` 119 | AccountGroupCreationMode string `json:"accountGroupCreationMode"` 120 | Credentials GcpOrgCredentials `json:"credentials"` 121 | HierarchySelection []HierarchySelection `json:"hierarchySelection"` 122 | } 123 | type Oci struct { 124 | AccountId string `json:"accountId"` 125 | AccountType string `json:"accountType"` 126 | Enabled bool `json:"enabled"` 127 | Name string `json:"name"` 128 | DefaultAccountGroupId string `json:"defaultAccountGroupId"` 129 | GroupName string `json:"groupName"` 130 | HomeRegion string `json:"homeRegion"` 131 | PolicyName string `json:"policyName"` 132 | UserName string `json:"userName"` 133 | UserOcid string `json:"userOcid"` 134 | } 135 | -------------------------------------------------------------------------------- /cloud/account/structs.go: -------------------------------------------------------------------------------- 1 | package account 2 | 3 | type AccountAndCredentials struct { 4 | Account Account `json:"cloudAccount"` 5 | } 6 | 7 | type NameTypeId struct { 8 | Name string `json:"name"` 9 | CloudType string `json:"cloudType"` 10 | AccountId string `json:"id"` 11 | } 12 | 13 | type Account struct { 14 | Name string `json:"name"` 15 | CloudType string `json:"cloudType"` 16 | AccountType string `json:"accountType"` 17 | Enabled bool `json:"enabled"` 18 | LastModifiedTs int `json:"lastModifiedTs"` 19 | LastModifiedBy string `json:"lastModifiedBy"` 20 | StorageScanEnabled bool `json:"storageScanEnabled"` 21 | ProtectionMode string `json:"protectionMode"` 22 | IngestionMode int `json:"ingestionMode"` 23 | GroupIds []string `json:"groupIds"` 24 | Groups []Group `json:"groups"` 25 | Status string `json:"status"` 26 | NumberOfChildAccounts int `json:"numberOfChildAccounts"` 27 | AccountId string `json:"accountId,omitempty"` 28 | AddedOn int `json:"addedOn"` 29 | } 30 | 31 | type Group struct { 32 | Id string `json:"id"` 33 | Name string `json:"name"` 34 | } 35 | 36 | type Aws struct { 37 | AccountId string `json:"accountId"` 38 | Enabled bool `json:"enabled"` 39 | ExternalId string `json:"externalId"` 40 | GroupIds []string `json:"groupIds"` 41 | Name string `json:"name"` 42 | RoleArn string `json:"roleArn"` 43 | ProtectionMode string `json:"protectionMode"` 44 | AccountType string `json:"accountType"` 45 | } 46 | 47 | type CloudAccount struct { 48 | AccountId string `json:"accountId"` 49 | Enabled bool `json:"enabled"` 50 | GroupIds []string `json:"groupIds"` 51 | Name string `json:"name"` 52 | ProtectionMode string `json:"protectionMode"` 53 | AccountType string `json:"accountType"` 54 | } 55 | 56 | type Azure struct { 57 | Account CloudAccount `json:"cloudAccount"` 58 | ClientId string `json:"clientId"` 59 | Key string `json:"key"` 60 | MonitorFlowLogs bool `json:"monitorFlowLogs"` 61 | TenantId string `json:"tenantId"` 62 | ServicePrincipalId string `json:"servicePrincipalId"` 63 | } 64 | 65 | type GcpCredentials struct { 66 | Type string `json:"type"` 67 | ProjectId string `json:"project_id"` 68 | PrivateKeyId string `json:"private_key_id"` 69 | PrivateKey string `json:"private_key"` 70 | ClientEmail string `json:"client_email"` 71 | ClientId string `json:"client_id"` 72 | AuthUri string `json:"auth_uri"` 73 | TokenUri string `json:"token_uri"` 74 | ProviderCertUrl string `json:"auth_provider_x509_cert_url"` 75 | ClientCertUrl string `json:"client_x509_cert_url"` 76 | } 77 | 78 | type Gcp struct { 79 | Account CloudAccount `json:"cloudAccount"` 80 | CompressionEnabled bool `json:"compressionEnabled"` 81 | DataflowEnabledProject string `json:"dataflowEnabledProject"` 82 | FlowLogStorageBucket string `json:"flowLogStorageBucket"` 83 | Credentials GcpCredentials `json:"credentials"` 84 | } 85 | 86 | type Alibaba struct { 87 | AccountId string `json:"accountId"` 88 | GroupIds []string `json:"groupIds"` 89 | Name string `json:"name"` 90 | RamArn string `json:"ramArn"` 91 | Enabled bool `json:"enabled"` 92 | } 93 | -------------------------------------------------------------------------------- /collection/const.go: -------------------------------------------------------------------------------- 1 | package collection 2 | 3 | const ( 4 | singular = "collection" 5 | plural = "collections" 6 | ) 7 | 8 | var Suffix = []string{"entitlement", "api", "v1", "collection"} 9 | -------------------------------------------------------------------------------- /collection/funcs.go: -------------------------------------------------------------------------------- 1 | package collection 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | pc "github.com/paloaltonetworks/prisma-cloud-go" 8 | ) 9 | 10 | func List(c pc.PrismaCloudClient) (Response, error) { 11 | c.Log(pc.LogAction, "(get) list of %s", plural) 12 | 13 | var res Response 14 | path := make([]string, 0, len(Suffix)+1) 15 | path = append(path, Suffix...) 16 | if _, err := c.Communicate("GET", path, nil, nil, &res); err != nil { 17 | return res, err 18 | } 19 | return res, nil 20 | } 21 | 22 | // Get returns the Collection. 23 | func Get(c pc.PrismaCloudClient, id string) (Collection, error) { 24 | c.Log(pc.LogAction, "(get) %s id:%s", singular, id) 25 | path := make([]string, 0, len(Suffix)+1) 26 | path = append(path, Suffix...) 27 | path = append(path, id) 28 | var template Collection 29 | if _, err := c.Communicate("GET", path, nil, nil, &template); err != nil { 30 | return Collection{}, err 31 | } 32 | return template, nil 33 | } 34 | 35 | // Create adds a new ResourceList. 36 | func Create(c pc.PrismaCloudClient, template CollectionRequest) (Collection, error) { 37 | return createUpdate(false, c, template, "") 38 | } 39 | func Delete(c pc.PrismaCloudClient, id string) error { 40 | c.Log(pc.LogAction, "(delete) %s id:%s", singular, id) 41 | path := make([]string, 0, len(Suffix)+1) 42 | path = append(path, Suffix...) 43 | path = append(path, id) 44 | _, err := c.Communicate("GET", path, nil, nil, nil) 45 | if err != nil { 46 | return err 47 | } 48 | _, err = c.Communicate("DELETE", path, nil, nil, nil) 49 | if err != nil { 50 | return err 51 | 52 | } 53 | return err 54 | } 55 | 56 | // Update modifies the existing CollectionTemplate. 57 | func Update(c pc.PrismaCloudClient, template CollectionRequest, id string) (Collection, error) { 58 | return createUpdate(true, c, template, id) 59 | } 60 | func createUpdate(exists bool, c pc.PrismaCloudClient, template CollectionRequest, id string) (Collection, error) { 61 | var ( 62 | logMsg strings.Builder 63 | method string 64 | ) 65 | logMsg.Grow(30) 66 | logMsg.WriteString("(") 67 | if exists { 68 | logMsg.WriteString("update") 69 | method = "PUT" 70 | } else { 71 | logMsg.WriteString("create") 72 | method = "POST" 73 | } 74 | logMsg.WriteString(") ") 75 | logMsg.WriteString(singular) 76 | if exists { 77 | fmt.Fprintf(&logMsg, ":%s", template.Name) 78 | } 79 | c.Log(pc.LogAction, logMsg.String()) 80 | 81 | path := make([]string, 0, len(Suffix)+1) 82 | path = append(path, Suffix...) 83 | if exists { 84 | path = append(path, id) 85 | } 86 | var templateRes Collection 87 | var err error 88 | if exists { 89 | _, err = c.Communicate(method, path, nil, template, nil) 90 | } else { 91 | _, err = c.Communicate(method, path, nil, template, &templateRes) 92 | } 93 | return templateRes, err 94 | } 95 | -------------------------------------------------------------------------------- /collection/structs.go: -------------------------------------------------------------------------------- 1 | package collection 2 | 3 | type Collection struct { 4 | Id string `json:"id,omitempty"` 5 | Name string `json:"name"` 6 | Description string `json:"description"` 7 | CreatedBy string `json:"createdBy"` 8 | CreatedTs int64 `json:"createdTs"` 9 | LastModifiedBy string `json:"lastModifiedBy"` 10 | LastModifiedTs int64 `json:"lastModifiedTs"` 11 | AssetGroups AssetGroups `json:"assetGroups"` 12 | } 13 | 14 | type AssetGroups struct { 15 | AccountGroupIds []string `json:"accountGroupIds,omitempty"` 16 | AccountIds []string `json:"accountIds,omitempty"` 17 | RepositoryIds []string `json:"repositoryIds,omitempty"` 18 | } 19 | 20 | type Response struct { 21 | Value []Collection `json:"value"` 22 | NextPageToken string `json:"nextPageToken"` 23 | } 24 | 25 | // To Create A new Collection 26 | type CollectionRequest struct { 27 | Name string `json:"name"` 28 | Description string `json:"description"` 29 | AssetGroups AssetGroups `json:"assetGroups"` 30 | } 31 | -------------------------------------------------------------------------------- /compliance/standard/const.go: -------------------------------------------------------------------------------- 1 | package standard 2 | 3 | const ( 4 | singular = "compliance standard" 5 | plural = "compliance standards" 6 | ) 7 | 8 | var Suffix = []string{"compliance"} 9 | -------------------------------------------------------------------------------- /compliance/standard/funcs.go: -------------------------------------------------------------------------------- 1 | package standard 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | pc "github.com/paloaltonetworks/prisma-cloud-go" 8 | ) 9 | 10 | // List returns all system supported and custom compliance standards. 11 | func List(c pc.PrismaCloudClient) ([]Standard, error) { 12 | c.Log(pc.LogAction, "(get) list of %s", plural) 13 | 14 | var ans []Standard 15 | if _, err := c.Communicate("GET", Suffix, nil, nil, &ans); err != nil { 16 | return nil, err 17 | } 18 | 19 | return ans, nil 20 | } 21 | 22 | // Identify returns the ID for the given compliance standard name. 23 | func Identify(c pc.PrismaCloudClient, name string) (string, error) { 24 | c.Log(pc.LogAction, "(get) id for %s name:%s", singular, name) 25 | 26 | list, err := List(c) 27 | if err != nil { 28 | return "", err 29 | } 30 | 31 | for _, o := range list { 32 | if o.Name == name { 33 | return o.Id, nil 34 | } 35 | } 36 | 37 | return "", pc.ObjectNotFoundError 38 | } 39 | 40 | // Get returns the compliance standard for the specified ID. 41 | func Get(c pc.PrismaCloudClient, id string) (Standard, error) { 42 | c.Log(pc.LogAction, "(get) %s id:%s", singular, id) 43 | 44 | path := make([]string, 0, len(Suffix)+1) 45 | path = append(path, Suffix...) 46 | path = append(path, id) 47 | 48 | var ans Standard 49 | _, err := c.Communicate("GET", path, nil, nil, &ans) 50 | return ans, err 51 | } 52 | 53 | // Create allows for the creation of a custom compliance standard. 54 | func Create(c pc.PrismaCloudClient, cs Standard) error { 55 | return createUpdate(false, c, cs) 56 | } 57 | 58 | // Update updates an existing compliance standard. 59 | func Update(c pc.PrismaCloudClient, cs Standard) error { 60 | return createUpdate(true, c, cs) 61 | } 62 | 63 | // Delete removes the compliance standard for the specified ID. 64 | func Delete(c pc.PrismaCloudClient, id string) error { 65 | c.Log(pc.LogAction, "(delete) %s id:%s", singular, id) 66 | 67 | path := make([]string, 0, len(Suffix)+1) 68 | path = append(path, Suffix...) 69 | path = append(path, id) 70 | _, err := c.Communicate("DELETE", path, nil, nil, nil) 71 | return err 72 | } 73 | 74 | func createUpdate(exists bool, c pc.PrismaCloudClient, cs Standard) error { 75 | var ( 76 | logMsg strings.Builder 77 | method string 78 | ) 79 | 80 | logMsg.Grow(30) 81 | logMsg.WriteString("(") 82 | if exists { 83 | logMsg.WriteString("update") 84 | method = "PUT" 85 | } else { 86 | logMsg.WriteString("create") 87 | method = "POST" 88 | } 89 | logMsg.WriteString(") ") 90 | 91 | logMsg.WriteString(singular) 92 | if exists { 93 | fmt.Fprintf(&logMsg, ": %s", cs.Id) 94 | } 95 | 96 | c.Log(pc.LogAction, logMsg.String()) 97 | 98 | path := make([]string, 0, len(Suffix)+1) 99 | path = append(path, Suffix...) 100 | if exists { 101 | path = append(path, cs.Id) 102 | } 103 | 104 | _, err := c.Communicate(method, path, nil, cs, nil) 105 | return err 106 | } 107 | -------------------------------------------------------------------------------- /compliance/standard/requirement/const.go: -------------------------------------------------------------------------------- 1 | package requirement 2 | 3 | const ( 4 | singular = "compliance standard requirement" 5 | plural = "compliance standard requirements" 6 | ) 7 | 8 | func ComplianceSuffix(cid string) []string { 9 | return []string{"compliance", cid, "requirement"} 10 | } 11 | 12 | func RequirementSuffix(id string) []string { 13 | return []string{"compliance", "requirement", id} 14 | } 15 | -------------------------------------------------------------------------------- /compliance/standard/requirement/funcs.go: -------------------------------------------------------------------------------- 1 | package requirement 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | pc "github.com/paloaltonetworks/prisma-cloud-go" 8 | ) 9 | 10 | // List returns a list of all compliance requirements for the specified compliance standard ID. 11 | func List(c pc.PrismaCloudClient, cid string) ([]Requirement, error) { 12 | c.Log(pc.LogAction, "(get) list of %s", plural) 13 | 14 | var ans []Requirement 15 | if _, err := c.Communicate("GET", ComplianceSuffix(cid), nil, nil, &ans); err != nil { 16 | return nil, err 17 | } 18 | 19 | return ans, nil 20 | } 21 | 22 | // Identify returns the ID for the given compliance standard requirement name. 23 | func Identify(c pc.PrismaCloudClient, cid, name string) (string, error) { 24 | c.Log(pc.LogAction, "(get) id for %s name:%s", singular, name) 25 | 26 | list, err := List(c, cid) 27 | if err != nil { 28 | return "", err 29 | } 30 | 31 | for _, o := range list { 32 | if o.Name == name { 33 | return o.Id, nil 34 | } 35 | } 36 | 37 | return "", pc.ObjectNotFoundError 38 | } 39 | 40 | // Get returns the compliance requirement data for the specified requirements ID. 41 | func Get(c pc.PrismaCloudClient, id string) (Requirement, error) { 42 | c.Log(pc.LogAction, "(get) %s id:%s", singular, id) 43 | 44 | var ans Requirement 45 | path := RequirementSuffix(id) 46 | 47 | _, err := c.Communicate("GET", path, nil, nil, &ans) 48 | return ans, err 49 | } 50 | 51 | // Create allows for the creation of a custom compliance standard. 52 | func Create(c pc.PrismaCloudClient, req Requirement) error { 53 | return createUpdate(false, c, req) 54 | } 55 | 56 | // Update updates an existing compliance standard. 57 | func Update(c pc.PrismaCloudClient, req Requirement) error { 58 | return createUpdate(true, c, req) 59 | } 60 | 61 | // Delete removes the compliance standard for the specified ID. 62 | func Delete(c pc.PrismaCloudClient, id string) error { 63 | c.Log(pc.LogAction, "(delete) %s id:%s", singular, id) 64 | 65 | path := RequirementSuffix(id) 66 | _, err := c.Communicate("DELETE", path, nil, nil, nil) 67 | return err 68 | } 69 | 70 | func createUpdate(exists bool, c pc.PrismaCloudClient, req Requirement) error { 71 | var ( 72 | logMsg strings.Builder 73 | method string 74 | path []string 75 | ) 76 | 77 | logMsg.Grow(30) 78 | logMsg.WriteString("(") 79 | if exists { 80 | logMsg.WriteString("update") 81 | method = "PUT" 82 | path = RequirementSuffix(req.Id) 83 | } else { 84 | logMsg.WriteString("create") 85 | method = "POST" 86 | path = ComplianceSuffix(req.ComplianceId) 87 | } 88 | logMsg.WriteString(") ") 89 | 90 | logMsg.WriteString(singular) 91 | if exists { 92 | fmt.Fprintf(&logMsg, ": %s", req.Id) 93 | } 94 | 95 | c.Log(pc.LogAction, logMsg.String()) 96 | 97 | _, err := c.Communicate(method, path, nil, req, nil) 98 | return err 99 | } 100 | -------------------------------------------------------------------------------- /compliance/standard/requirement/section/const.go: -------------------------------------------------------------------------------- 1 | package section 2 | 3 | const ( 4 | singular = "compliance standard requirement section" 5 | plural = "compliance standard requirement sections" 6 | ) 7 | 8 | func RequirementSuffix(id string) []string { 9 | return []string{"compliance", id, "section"} 10 | } 11 | 12 | func SectionSuffix(id string) []string { 13 | return []string{"compliance", "requirement", "section", id} 14 | } 15 | -------------------------------------------------------------------------------- /compliance/standard/requirement/section/funcs.go: -------------------------------------------------------------------------------- 1 | package section 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | pc "github.com/paloaltonetworks/prisma-cloud-go" 8 | ) 9 | 10 | // List returns a list of all compliance requirements sections for the specified compliance requirement ID. 11 | func List(c pc.PrismaCloudClient, rid string) ([]Section, error) { 12 | c.Log(pc.LogAction, "(get) list of %s", plural) 13 | 14 | var ans []Section 15 | if _, err := c.Communicate("GET", RequirementSuffix(rid), nil, nil, &ans); err != nil { 16 | return nil, err 17 | } 18 | 19 | return ans, nil 20 | } 21 | 22 | // GetId returns the compliance requirement section data for the specified ID. 23 | func GetId(c pc.PrismaCloudClient, rid, id string) (Section, error) { 24 | list, err := List(c, rid) 25 | if err != nil { 26 | return Section{}, err 27 | } 28 | 29 | for _, o := range list { 30 | if o.Id == id { 31 | return o, nil 32 | } 33 | } 34 | 35 | return Section{}, pc.ObjectNotFoundError 36 | } 37 | 38 | // Get returns the compliance requirement section data for the specified requirements section ID. 39 | func Get(c pc.PrismaCloudClient, rid, sectionId string) (Section, error) { 40 | list, err := List(c, rid) 41 | if err != nil { 42 | return Section{}, err 43 | } 44 | 45 | for _, o := range list { 46 | if o.SectionId == sectionId { 47 | return o, nil 48 | } 49 | } 50 | 51 | return Section{}, pc.ObjectNotFoundError 52 | } 53 | 54 | // Create allows for the creation of a custom compliance standard. 55 | func Create(c pc.PrismaCloudClient, s Section) error { 56 | return createUpdate(false, c, s) 57 | } 58 | 59 | // Update updates an existing compliance standard. 60 | func Update(c pc.PrismaCloudClient, s Section) error { 61 | return createUpdate(true, c, s) 62 | } 63 | 64 | // Delete removes the compliance standard for the specified ID. 65 | func Delete(c pc.PrismaCloudClient, id string) error { 66 | c.Log(pc.LogAction, "(delete) %s id:%s", singular, id) 67 | 68 | path := SectionSuffix(id) 69 | _, err := c.Communicate("DELETE", path, nil, nil, nil) 70 | return err 71 | } 72 | 73 | func createUpdate(exists bool, c pc.PrismaCloudClient, s Section) error { 74 | var ( 75 | logMsg strings.Builder 76 | method string 77 | path []string 78 | ) 79 | 80 | logMsg.Grow(30) 81 | logMsg.WriteString("(") 82 | if exists { 83 | logMsg.WriteString("update") 84 | method = "PUT" 85 | path = SectionSuffix(s.Id) 86 | } else { 87 | logMsg.WriteString("create") 88 | method = "POST" 89 | path = RequirementSuffix(s.RequirementId) 90 | } 91 | logMsg.WriteString(") ") 92 | 93 | logMsg.WriteString(singular) 94 | if exists { 95 | fmt.Fprintf(&logMsg, ": %s", s.Id) 96 | } 97 | 98 | c.Log(pc.LogAction, logMsg.String()) 99 | 100 | _, err := c.Communicate(method, path, nil, s, nil) 101 | return err 102 | } 103 | -------------------------------------------------------------------------------- /compliance/standard/requirement/section/structs.go: -------------------------------------------------------------------------------- 1 | package section 2 | 3 | type Section struct { 4 | Id string `json:"id,omitempty"` 5 | Description string `json:"description,omitempty"` 6 | CreatedBy string `json:"createdBy,omitempty"` 7 | CreatedOn int `json:"createdOn,omitempty"` 8 | LastModifiedBy string `json:"lastModifiedBy,omitempty"` 9 | LastModifiedOn int `json:"lastModifiedOn,omitempty"` 10 | SystemDefault bool `json:"systemDefault,omitempty"` 11 | PoliciesAssignedCount int `json:"policiesAssignedCount,omitempty"` 12 | StandardName string `json:"standardName"` 13 | RequirementId string `json:"-"` 14 | RequirementName string `json:"requirementName,omitempty"` 15 | SectionId string `json:"sectionId,omitempty"` 16 | Label string `json:"label,omitempty"` 17 | ViewOrder int `json:"viewOrder,omitempty"` 18 | AssociatedPolicyIds []string `json:"associatedPolicyIds,omitempty"` 19 | } 20 | -------------------------------------------------------------------------------- /compliance/standard/requirement/structs.go: -------------------------------------------------------------------------------- 1 | package requirement 2 | 3 | type Requirement struct { 4 | Name string `json:"name"` 5 | Id string `json:"id,omitempty"` 6 | Description string `json:"description,omitempty"` 7 | CreatedBy string `json:"createdBy,omitempty"` 8 | CreatedOn int `json:"createdOn,omitempty"` 9 | LastModifiedBy string `json:"lastModifiedBy,omitempty"` 10 | LastModifiedOn int `json:"lastModifiedOn,omitempty"` 11 | SystemDefault bool `json:"systemDefault,omitempty"` 12 | PoliciesAssignedCount int `json:"policiesAssignedCount,omitempty"` 13 | ComplianceId string `json:"-"` 14 | StandardName string `json:"standardName"` 15 | RequirementId string `json:"requirementId"` 16 | ViewOrder int `json:"viewOrder,omitempty"` 17 | } 18 | -------------------------------------------------------------------------------- /compliance/standard/structs.go: -------------------------------------------------------------------------------- 1 | package standard 2 | 3 | type Standard struct { 4 | Name string `json:"name"` 5 | Id string `json:"id,omitempty"` 6 | Description string `json:"description,omitempty"` 7 | CreatedBy string `json:"createdBy,omitempty"` 8 | CreatedOn int `json:"createdOn,omitempty"` 9 | LastModifiedBy string `json:"lastModifiedBy,omitempty"` 10 | LastModifiedOn int `json:"lastModifiedOn,omitempty"` 11 | SystemDefault bool `json:"systemDefault,omitempty"` 12 | PoliciesAssignedCount int `json:"policiesAssignedCount,omitempty"` 13 | CloudTypes []string `json:"cloudType,omitempty"` 14 | } 15 | -------------------------------------------------------------------------------- /const.go: -------------------------------------------------------------------------------- 1 | package prismacloud 2 | 3 | // These are the hidden fields blanked out during send and receive logging. 4 | var SensitiveKeys = []string{"password", "private_key", "external_id"} 5 | 6 | // Control what is echoed to the user. 7 | const ( 8 | LogQuiet = "quiet" 9 | LogAction = "action" 10 | LogPath = "path" 11 | LogSend = "send" 12 | LogReceive = "receive" 13 | ) 14 | -------------------------------------------------------------------------------- /data-security/datapattern/const.go: -------------------------------------------------------------------------------- 1 | package datapattern 2 | 3 | const ( 4 | singular = "data pattern" 5 | plural = "data patterns" 6 | ) 7 | 8 | var Suffix = []string{"pcds", "config", "v3", "dss-api", "data-pattern", "dssTenantId"} 9 | 10 | var TenantSuffix = []string{"api", "v1", "provision", "dlp", "status"} 11 | 12 | var listBody = ListBody{ModeFilter: []string{"predefined", "custom"}} 13 | -------------------------------------------------------------------------------- /data-security/datapattern/funcs.go: -------------------------------------------------------------------------------- 1 | package datapattern 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | pc "github.com/paloaltonetworks/prisma-cloud-go" 8 | ) 9 | 10 | // GetTenantId returns dlp tenant id. 11 | func GetTenantId(c pc.PrismaCloudClient) (string, error) { 12 | c.Log(pc.LogAction, "(get) prisma id") 13 | 14 | var ans TenantInfo 15 | 16 | path := make([]string, 0, len(TenantSuffix)+1) 17 | path = append(path, TenantSuffix...) 18 | 19 | _, err := c.Communicate("GET", path, nil, nil, &ans) 20 | return ans.DlpTenantId, err 21 | } 22 | 23 | // List returns a list of available data patterns 24 | func List(c pc.PrismaCloudClient) ([]Pattern, error) { 25 | c.Log(pc.LogAction, "(get) list of %s", plural) 26 | 27 | var ans ListBody 28 | path := make([]string, 0, len(Suffix)+1) 29 | path = append(path, Suffix...) 30 | dlpTenantId, err1 := GetTenantId(c) 31 | if err1 != nil { 32 | return nil, err1 33 | } 34 | 35 | path = append(path, dlpTenantId) 36 | 37 | _, err := c.Communicate("GET", path, nil, listBody, &ans) 38 | return ans.Patterns, err 39 | } 40 | 41 | // Identify returns the ID for the given data pattern. 42 | func Identify(c pc.PrismaCloudClient, name string) (string, error) { 43 | c.Log(pc.LogAction, "(get) id for %s name:%s", singular, name) 44 | 45 | list, err := List(c) 46 | if err != nil { 47 | return "", err 48 | } 49 | 50 | for _, o := range list { 51 | if o.Name == name { 52 | return o.Id, nil 53 | } 54 | } 55 | 56 | return "", pc.ObjectNotFoundError 57 | } 58 | 59 | // Get returns the data pattern that has the specified ID. 60 | func Get(c pc.PrismaCloudClient, id string) (Pattern, error) { 61 | c.Log(pc.LogAction, "(get) %s id:%s", singular, id) 62 | 63 | var ans Pattern 64 | list, err := List(c) 65 | if err != nil { 66 | return ans, err 67 | } 68 | 69 | for _, o := range list { 70 | if o.Id == id { 71 | ans = o 72 | } 73 | } 74 | return ans, err 75 | } 76 | 77 | // Create adds a new data pattern. 78 | func Create(c pc.PrismaCloudClient, pattern Pattern) error { 79 | return createUpdate(false, c, pattern) 80 | } 81 | 82 | // Update modifies the existing data pattern. 83 | func Update(c pc.PrismaCloudClient, pattern Pattern) error { 84 | return createUpdate(true, c, pattern) 85 | } 86 | 87 | // Delete removes a data pattern using its ID. 88 | func Delete(c pc.PrismaCloudClient, id string) error { 89 | c.Log(pc.LogAction, "(delete) %s id:%s", singular, id) 90 | 91 | path := make([]string, 0, len(Suffix)+1) 92 | path = append(path, Suffix...) 93 | dlpTenantId, err1 := GetTenantId(c) 94 | if err1 != nil { 95 | return err1 96 | } 97 | path = append(path, dlpTenantId) 98 | path = append(path, "pattern-id") 99 | path = append(path, id) 100 | _, err := c.Communicate("DELETE", path, nil, nil, nil) 101 | return err 102 | } 103 | 104 | func createUpdate(exists bool, c pc.PrismaCloudClient, pattern Pattern) error { 105 | var ( 106 | logMsg strings.Builder 107 | method string 108 | ) 109 | 110 | logMsg.Grow(30) 111 | logMsg.WriteString("(") 112 | if exists { 113 | logMsg.WriteString("update") 114 | method = "PUT" 115 | } else { 116 | logMsg.WriteString("create") 117 | method = "POST" 118 | } 119 | logMsg.WriteString(") ") 120 | 121 | logMsg.WriteString(singular) 122 | if exists { 123 | fmt.Fprintf(&logMsg, ":%s", pattern.Id) 124 | } 125 | 126 | c.Log(pc.LogAction, logMsg.String()) 127 | 128 | path := make([]string, 0, len(Suffix)+1) 129 | path = append(path, Suffix...) 130 | dlpTenantId, err1 := GetTenantId(c) 131 | if err1 != nil { 132 | return err1 133 | } 134 | path = append(path, dlpTenantId) 135 | if exists { 136 | path = append(path, "pattern-id") 137 | path = append(path, pattern.Id) 138 | } 139 | 140 | _, err := c.Communicate(method, path, nil, pattern, nil) 141 | return err 142 | } 143 | -------------------------------------------------------------------------------- /data-security/datapattern/structs.go: -------------------------------------------------------------------------------- 1 | package datapattern 2 | 3 | type Pattern struct { 4 | Id string `json:"id,omitempty"` 5 | Name string `json:"name"` 6 | Description string `json:"description"` 7 | Mode string `json:"mode,omitempty"` 8 | DetectionTechnique string `json:"detectionTechnique"` 9 | Entity string `json:"entity,omitempty"` 10 | Grammar string `json:"grammar,omitempty"` 11 | ParentId string `json:"parentId,omitempty"` 12 | ProximityKeywords []string `json:"proximityKeywords,omitempty"` 13 | Regexes []RegexInfo `json:"regexes"` 14 | RootType string `json:"rootType,omitempty"` 15 | S3Path string `json:"s3Path,omitempty"` 16 | CreatedBy string `json:"createdBy,omitempty"` 17 | UpdatedBy string `json:"updatedBy,omitempty"` 18 | UpdatedAt int `json:"updatedAt,omitempty"` 19 | IsEditable bool `json:"isEditable,omitempty"` 20 | } 21 | 22 | type RegexInfo struct { 23 | Regex string `json:"regex"` 24 | Weight int `json:"weight,omitempty"` 25 | } 26 | 27 | type ListBody struct { 28 | ModeFilter []string `json:"modeFilter"` 29 | LastUpdatedByFilter []string `json:"lastUpdatedByFilter"` 30 | Patterns []Pattern `json:"patterns"` 31 | } 32 | type TenantInfo struct { 33 | DlpTenantId string `json:"dlpTenantId"` 34 | } 35 | -------------------------------------------------------------------------------- /data-security/dataprofile/const.go: -------------------------------------------------------------------------------- 1 | package dataprofile 2 | 3 | const ( 4 | singular = "data profile" 5 | plural = "data profiles" 6 | ) 7 | 8 | var Suffix = []string{"pcds", "config", "v3", "dss-api", "data-profile", "dssTenantId"} 9 | 10 | var TenantSuffix = []string{"api", "v1", "provision", "dlp", "status"} 11 | -------------------------------------------------------------------------------- /data-security/dataprofile/funcs.go: -------------------------------------------------------------------------------- 1 | package dataprofile 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | pc "github.com/paloaltonetworks/prisma-cloud-go" 8 | ) 9 | 10 | // GetTenantId returns dlp tenant id. 11 | func GetTenantId(c pc.PrismaCloudClient) (string, error) { 12 | c.Log(pc.LogAction, "(get) prisma id") 13 | 14 | var ans TenantInfo 15 | 16 | path := make([]string, 0, len(TenantSuffix)+1) 17 | path = append(path, TenantSuffix...) 18 | 19 | _, err := c.Communicate("GET", path, nil, nil, &ans) 20 | return ans.DlpTenantId, err 21 | } 22 | 23 | // List returns a list of available custom data profiles. 24 | func List(c pc.PrismaCloudClient) ([]ListProfile, error) { 25 | c.Log(pc.LogAction, "(get) list of %s", plural) 26 | 27 | var ans ListBody 28 | path := make([]string, 0, len(Suffix)+1) 29 | path = append(path, Suffix...) 30 | 31 | dlpTenantId, err1 := GetTenantId(c) 32 | if err1 != nil { 33 | return nil, err1 34 | } 35 | 36 | path = append(path, dlpTenantId) 37 | _, err := c.Communicate("GET", path, nil, nil, &ans) 38 | return ans.Profiles, err 39 | } 40 | 41 | // Identify returns the ID for the given data profile. 42 | func Identify(c pc.PrismaCloudClient, name string) (string, error) { 43 | c.Log(pc.LogAction, "(get) id for %s name:%s", singular, name) 44 | 45 | list, err := List(c) 46 | 47 | if err != nil { 48 | return "", err 49 | } 50 | 51 | for _, o := range list { 52 | if o.Name == name { 53 | return o.Id, nil 54 | } 55 | } 56 | 57 | return "", pc.ObjectNotFoundError 58 | } 59 | 60 | // Get returns the data profile that has the specified ID. 61 | func Get(c pc.PrismaCloudClient, id string) (Profile, error) { 62 | c.Log(pc.LogAction, "(get) %s id:%s", singular, id) 63 | 64 | var ans Profile 65 | 66 | path := make([]string, 0, len(Suffix)+1) 67 | path = append(path, Suffix...) 68 | 69 | dlpTenantId, err1 := GetTenantId(c) 70 | if err1 != nil { 71 | return ans, err1 72 | } 73 | 74 | path = append(path, dlpTenantId) 75 | path = append(path, "id") 76 | path = append(path, id) 77 | 78 | _, err := c.Communicate("GET", path, nil, nil, &ans) 79 | 80 | return ans, err 81 | } 82 | 83 | // Create adds a new data profile. 84 | func Create(c pc.PrismaCloudClient, profile Profile) error { 85 | return createUpdate(false, c, profile) 86 | } 87 | 88 | // Update modifies the existing data profile. 89 | func Update(c pc.PrismaCloudClient, profile Profile) error { 90 | return createUpdate(true, c, profile) 91 | } 92 | 93 | // Delete removes a data profile using its ID. 94 | func Delete(c pc.PrismaCloudClient, id string) error { 95 | c.Log(pc.LogAction, "(delete) %s id:%s", singular, id) 96 | 97 | path := make([]string, 0, len(Suffix)+1) 98 | path = append(path, Suffix...) 99 | 100 | dlpTenantId, err1 := GetTenantId(c) 101 | if err1 != nil { 102 | return err1 103 | } 104 | 105 | path = append(path, dlpTenantId) 106 | path = append(path, "id") 107 | path = append(path, id) 108 | _, err := c.Communicate("DELETE", path, nil, nil, nil) 109 | return err 110 | } 111 | 112 | func createUpdate(exists bool, c pc.PrismaCloudClient, profile Profile) error { 113 | var ( 114 | logMsg strings.Builder 115 | method string 116 | ) 117 | 118 | logMsg.Grow(30) 119 | logMsg.WriteString("(") 120 | if exists { 121 | logMsg.WriteString("update") 122 | method = "PUT" 123 | } else { 124 | logMsg.WriteString("create") 125 | method = "POST" 126 | } 127 | logMsg.WriteString(") ") 128 | 129 | logMsg.WriteString(singular) 130 | if exists { 131 | fmt.Fprintf(&logMsg, ":%s", profile.Id) 132 | } 133 | 134 | c.Log(pc.LogAction, logMsg.String()) 135 | 136 | path := make([]string, 0, len(Suffix)+1) 137 | path = append(path, Suffix...) 138 | 139 | dlpTenantId, err1 := GetTenantId(c) 140 | if err1 != nil { 141 | return err1 142 | } 143 | 144 | path = append(path, dlpTenantId) 145 | if exists { 146 | path = append(path, "id") 147 | path = append(path, profile.Id) 148 | } 149 | 150 | _, err := c.Communicate(method, path, nil, profile, nil) 151 | return err 152 | } 153 | -------------------------------------------------------------------------------- /data-security/dataprofile/structs.go: -------------------------------------------------------------------------------- 1 | package dataprofile 2 | 3 | type Profile struct { 4 | Id string `json:"id,omitempty"` 5 | Name string `json:"name"` 6 | Description string `json:"description"` 7 | Types string `json:"types"` 8 | ProfileType string `json:"profileType"` 9 | TenantId string `json:"tenantId,omitempty"` 10 | Status string `json:"status"` 11 | ProfileStatus string `json:"profileStatus"` 12 | DataPatternsRulesOne DataPatternsRulesOne `json:"dataPatternsRulesOne,omitempty"` 13 | DataPatternsRule1 DataPatternsRule1 `json:"dataPatternsRule1"` 14 | CreatedBy string `json:"createdBy,omitempty"` 15 | UpdatedBy string `json:"updatedBy,omitempty"` 16 | CreatedAt string `json:"createdAt,omitempty"` 17 | UpdatedAt string `json:"updatedAt,omitempty"` 18 | } 19 | 20 | type ListProfile struct { 21 | Id string `json:"id,omitempty"` 22 | Name string `json:"name"` 23 | Type string `json:"type"` 24 | Status string `json:"status"` 25 | UpdatedAt int `json:"updatedAt,omitempty"` 26 | UpdatedBy string `json:"updatedBy,omitempty"` 27 | CreatedBy string `json:"createdBy,omitempty"` 28 | } 29 | 30 | type DataPatternsRulesOne struct { 31 | OperatorType string `json:"operatorType,omitempty"` 32 | DataPatternRules []DataPatternRuleOne `json:"dataPatternRules,omitempty"` 33 | } 34 | 35 | type DataPatternsRule1 struct { 36 | OperatorType string `json:"operatorType"` 37 | DataPatternRules []DataPatternRule1 `json:"dataPatternRules"` 38 | } 39 | 40 | type DataPatternRule1 struct { 41 | Id string `json:"id,omitempty"` 42 | Name string `json:"name"` 43 | DetectionTechnique string `json:"detectionTechnique"` 44 | MatchType string `json:"matchType"` 45 | OccurrenceOperatorType string `json:"occurrenceOperatorType"` 46 | OccurrenceCount int `json:"occurrenceCount,omitempty"` 47 | ConfidenceLevel string `json:"confidenceLevel"` 48 | SupportedConfidenceLevels []string `json:"supportedConfidenceLevels,omitempty"` 49 | OccurrenceHigh int `json:"occurrenceHigh,omitempty"` 50 | OccurrenceLow int `json:"occurrenceLow,omitempty"` 51 | } 52 | 53 | type DataPatternRuleOne struct { 54 | Id string `json:"id"` 55 | Name string `json:"name"` 56 | DetectionTechnique string `json:"detectionTechnique"` 57 | MatchType string `json:"matchType"` 58 | OccurrenceOperatorType string `json:"occurrenceOperatorType"` 59 | OccurrenceCount int `json:"occurrenceCount"` 60 | ConfidencLevel string `json:"confidencLevel"` 61 | SupportedConfidenceLevels []string `json:"supportedConfidenceLevels"` 62 | OccurrenceHigh int `json:"occurrenceHigh"` 63 | OccurrenceLow int `json:"occurrenceLow"` 64 | } 65 | 66 | type ListBody struct { 67 | Profiles []ListProfile `json:"profiles"` 68 | } 69 | 70 | type TenantInfo struct { 71 | DlpTenantId string `json:"dlpTenantId"` 72 | } 73 | -------------------------------------------------------------------------------- /doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package prismacloud is an SDK meant to assist in interacting with the Palo 3 | Alto Networks Prisma Cloud API. 4 | 5 | To connect, create a client connetion with the desired params and then 6 | initialize the connection: 7 | 8 | package main 9 | 10 | import ( 11 | "log" 12 | "github.com/paloaltonetworks/prisma-cloud-go" 13 | "github.com/paloaltonetworks/prisma-cloud-go/compliance/standard" 14 | ) 15 | 16 | func main() { 17 | client := &prismacloud.Client{} 18 | if err := c.Initialize("creds.json"); err != nil { 19 | log.Fatalf("Failed to connect: %s", err) 20 | } 21 | 22 | listing, err := standard.List(client) 23 | if err != nil { 24 | log.Fatalf("Failed to get compliance standards: %s", err) 25 | } 26 | 27 | log.Printf("Compliance standards:") 28 | for _, elm := range listing { 29 | log.Printf("* (%s) %s", elm.Id, elm.Name) 30 | } 31 | } 32 | 33 | In most cases the struct and types match what the Prisma Cloud API 34 | specifies, so you may find it useful to refer to the Prisma Cloud API 35 | for further information: https://api.docs.prismacloud.io/reference 36 | */ 37 | package prismacloud 38 | -------------------------------------------------------------------------------- /error.go: -------------------------------------------------------------------------------- 1 | package prismacloud 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "strings" 7 | ) 8 | 9 | var InvalidCredentialsError = errors.New("invalid credentials") 10 | var ObjectNotFoundError = errors.New("object not found") 11 | var AlreadyExistsError = errors.New("object already exists") 12 | var InvalidPermissionGroupIdError = errors.New("invalid_permission_group_id") //permission group 13 | var AccountGroupNotFoundError = errors.New("account_group_not_found") //account_group_not_found 14 | var InternalError = errors.New("internal_error") //compliance standard requirement 15 | var OverlappingCIDRError = errors.New("overlapping_cidr") 16 | var ResourceListNotFoundError = errors.New("non_existing_resource_list_id") //resource list 17 | var CollectionNotFoundError = errors.New("invalid_collection_id") //collection 18 | 19 | type PrismaCloudErrorList struct { 20 | Errors []PrismaCloudError 21 | Method string 22 | StatusCode int 23 | Path string 24 | } 25 | 26 | func (e PrismaCloudErrorList) Error() string { 27 | var buf strings.Builder 28 | buf.Grow(100) 29 | 30 | fmt.Fprintf(&buf, "%d/%s ", e.StatusCode, e.Path) 31 | for i := range e.Errors { 32 | if i != 0 { 33 | buf.WriteString(" ") 34 | } 35 | buf.WriteString(e.Errors[i].Error()) 36 | } 37 | 38 | return buf.String() 39 | } 40 | 41 | func (e PrismaCloudErrorList) GenericError() error { 42 | for i := range e.Errors { 43 | if e.Errors[i].InvalidPermissionGroupIdError() { 44 | return InvalidPermissionGroupIdError 45 | } else if e.Errors[i].AccountGroupNotFoundError() { 46 | return AccountGroupNotFoundError 47 | } else if e.Errors[i].ObjectNotFound() { 48 | return ObjectNotFoundError 49 | } else if e.Errors[i].AlreadyExists() { 50 | return AlreadyExistsError 51 | } else if e.Errors[i].InternalError() { 52 | return InternalError 53 | } else if e.Errors[i].OverlappingCIDRError() { 54 | return OverlappingCIDRError 55 | } else if e.Errors[i].ResourceListNotFoundError() { 56 | return ResourceListNotFoundError 57 | } else if e.Errors[i].CollectionNotFoundError() { 58 | return CollectionNotFoundError 59 | } 60 | } 61 | 62 | return nil 63 | } 64 | 65 | type PrismaCloudError struct { 66 | Message string `json:"i18nKey"` 67 | Severity string `json:"severity"` 68 | Subject string `json:"subject"` 69 | } 70 | 71 | func (e PrismaCloudError) ObjectNotFound() bool { 72 | switch e.Message { 73 | case "invalid_id", "not_found": 74 | return true 75 | } 76 | 77 | return false 78 | } 79 | func (e PrismaCloudError) InvalidPermissionGroupIdError() bool { 80 | return strings.HasSuffix(e.Message, "invalid_permission_group_id") 81 | } 82 | func (e PrismaCloudError) AlreadyExists() bool { 83 | return strings.HasSuffix(e.Message, "_already_exists") 84 | } 85 | 86 | func (e PrismaCloudError) OverlappingCIDRError() bool { 87 | return strings.HasSuffix(e.Message, "overlapping_cidr") 88 | } 89 | 90 | func (e PrismaCloudError) Error() string { 91 | return fmt.Sprintf("Error(msg:%s severity:%s subject:%v)", e.Message, e.Severity, e.Subject) 92 | } 93 | 94 | func (e PrismaCloudError) InternalError() bool { 95 | return strings.HasSuffix(e.Message, "internal_error") 96 | } 97 | func (e PrismaCloudError) AccountGroupNotFoundError() bool { 98 | return strings.HasSuffix(e.Message, "account_group_not_found") 99 | } 100 | func (e PrismaCloudError) ResourceListNotFoundError() bool { 101 | return strings.HasSuffix(e.Message, "non_existing_resource_list_id") 102 | } 103 | func (e PrismaCloudError) CollectionNotFoundError() bool { 104 | return strings.HasSuffix(e.Message, "invalid_collection_id") 105 | } 106 | -------------------------------------------------------------------------------- /funcs.go: -------------------------------------------------------------------------------- 1 | package prismacloud 2 | 3 | import ( 4 | "regexp" 5 | ) 6 | 7 | // scrubSensitiveData removes sensitive stuff from send/receive logging. 8 | func scrubSensitiveData(b []byte) string { 9 | s := string(b) 10 | 11 | for _, val := range SensitiveKeys { 12 | hdr := `"` + val + `":` 13 | pat := regexp.MustCompile(hdr + `".*?"`) 14 | s = pat.ReplaceAllString(s, hdr+`"********"`) 15 | } 16 | 17 | return s 18 | } 19 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/paloaltonetworks/prisma-cloud-go 2 | 3 | go 1.13 4 | 5 | require github.com/google/uuid v1.6.0 6 | -------------------------------------------------------------------------------- /integration/const.go: -------------------------------------------------------------------------------- 1 | package integration 2 | 3 | const ( 4 | singular = "integration" 5 | plural = "integrations" 6 | ) 7 | 8 | var Suffix = []string{"integration"} 9 | var v1Suffix = []string{"api", "v1", "tenant"} 10 | var LicenseSuffix = []string{"license"} 11 | 12 | var InboundIntegrations = []string{"okta_idp", "qualys", "tenable"} 13 | 14 | var OutboundIntegrations = []string{"slack", "splunk", "amazon_sqs", "webhook", "microsoft_teams", "azure_service_bus_queue", 15 | "service_now", "pager_duty", "demisto", "google_cscc", "aws_security_hub", "aws_s3", "snowflake"} 16 | -------------------------------------------------------------------------------- /integration/funcs.go: -------------------------------------------------------------------------------- 1 | package integration 2 | 3 | import ( 4 | "fmt" 5 | "net/url" 6 | "strings" 7 | 8 | pc "github.com/paloaltonetworks/prisma-cloud-go" 9 | ) 10 | 11 | // Types returns a list of all supported integration types. 12 | func Types(c pc.PrismaCloudClient) ([]string, error) { 13 | c.Log(pc.LogAction, "(get) list of %s types", singular) 14 | 15 | path := make([]string, 0, len(Suffix)+1) 16 | path = append(path, Suffix...) 17 | path = append(path, "type") 18 | 19 | var ans []string 20 | _, err := c.Communicate("GET", path, nil, nil, &ans) 21 | return ans, err 22 | } 23 | 24 | // GetPrismaId returns prisma id. 25 | func GetPrismaId(c pc.PrismaCloudClient) (string, error) { 26 | c.Log(pc.LogAction, "(get) prisma id") 27 | 28 | var ans LicenseInfo 29 | 30 | path := make([]string, 0, len(LicenseSuffix)+1) 31 | path = append(path, LicenseSuffix...) 32 | 33 | _, err := c.Communicate("GET", path, nil, nil, &ans) 34 | return ans.PrismaId, err 35 | } 36 | 37 | // List returns all your integrations, optionally filtered by type. 38 | func List(c pc.PrismaCloudClient, t string, prismaIdRequired bool) ([]Integration, error) { 39 | c.Log(pc.LogAction, "(get) list of %s", plural) 40 | 41 | var query url.Values 42 | if t != "" { 43 | query = url.Values{} 44 | query.Add("type", t) 45 | } 46 | 47 | var ans []Integration 48 | 49 | path := make([]string, 0, len(v1Suffix)+len(Suffix)+1) 50 | if prismaIdRequired { 51 | prismaId, err := GetPrismaId(c) 52 | if err != nil { 53 | return nil, err 54 | } 55 | 56 | path = append(path, v1Suffix...) 57 | path = append(path, prismaId) 58 | } 59 | 60 | path = append(path, Suffix...) 61 | if _, err := c.Communicate("GET", path, query, nil, &ans); err != nil { 62 | return nil, err 63 | } 64 | 65 | return ans, nil 66 | } 67 | 68 | // Identify returns the ID for the given integration name. 69 | func Identify(c pc.PrismaCloudClient, name string, prismaIdRequired bool) (string, error) { 70 | c.Log(pc.LogAction, "(get) id for %s: %s", singular, name) 71 | 72 | list, err := List(c, "", prismaIdRequired) 73 | if err != nil { 74 | return "", err 75 | } 76 | 77 | for _, o := range list { 78 | if o.Name == name { 79 | return o.Id, nil 80 | } 81 | } 82 | 83 | return "", pc.ObjectNotFoundError 84 | } 85 | 86 | // Get returns integration details for the specified ID. 87 | func Get(c pc.PrismaCloudClient, id string, prismaIdRequired bool) (Integration, error) { 88 | c.Log(pc.LogAction, "(get) %s: %s", singular, id) 89 | 90 | var ans Integration 91 | 92 | path := make([]string, 0, len(v1Suffix)+len(Suffix)+1) 93 | if prismaIdRequired { 94 | prismaId, err := GetPrismaId(c) 95 | if err != nil { 96 | return ans, err 97 | } 98 | 99 | path = append(path, v1Suffix...) 100 | path = append(path, prismaId) 101 | } 102 | 103 | path = append(path, Suffix...) 104 | path = append(path, id) 105 | 106 | _, err := c.Communicate("GET", path, nil, nil, &ans) 107 | return ans, err 108 | } 109 | 110 | // Create adds an integration with the specified external system. 111 | func Create(c pc.PrismaCloudClient, obj Integration, prismaIdRequired bool) error { 112 | return createUpdate(false, c, obj, prismaIdRequired) 113 | } 114 | 115 | // Update modifies the specified integration. 116 | func Update(c pc.PrismaCloudClient, obj Integration, prismaIdRequired bool) error { 117 | return createUpdate(true, c, obj, prismaIdRequired) 118 | } 119 | 120 | // Delete removes the integration for the specified ID. 121 | func Delete(c pc.PrismaCloudClient, id string, prismaIdRequired bool) error { 122 | c.Log(pc.LogAction, "(delete) %s: %s", singular, id) 123 | 124 | path := make([]string, 0, len(v1Suffix)+len(Suffix)+1) 125 | if prismaIdRequired { 126 | prismaId, err := GetPrismaId(c) 127 | if err != nil { 128 | return err 129 | } 130 | 131 | path = append(path, v1Suffix...) 132 | path = append(path, prismaId) 133 | } 134 | 135 | path = append(path, Suffix...) 136 | path = append(path, id) 137 | 138 | _, err := c.Communicate("DELETE", path, nil, nil, nil) 139 | return err 140 | } 141 | 142 | func createUpdate(exists bool, c pc.PrismaCloudClient, obj Integration, prismaIdRequired bool) error { 143 | var ( 144 | logMsg strings.Builder 145 | method string 146 | ) 147 | 148 | logMsg.Grow(30) 149 | logMsg.WriteString("(") 150 | if exists { 151 | logMsg.WriteString("update") 152 | method = "PUT" 153 | } else { 154 | logMsg.WriteString("create") 155 | method = "POST" 156 | } 157 | logMsg.WriteString(") ") 158 | 159 | logMsg.WriteString(singular) 160 | if exists { 161 | fmt.Fprintf(&logMsg, ": %s", obj.Id) 162 | } 163 | 164 | c.Log(pc.LogAction, logMsg.String()) 165 | 166 | path := make([]string, 0, len(v1Suffix)+len(Suffix)+1) 167 | if prismaIdRequired { 168 | prismaId, err := GetPrismaId(c) 169 | if err != nil { 170 | return err 171 | } 172 | 173 | path = append(path, v1Suffix...) 174 | path = append(path, prismaId) 175 | } 176 | 177 | path = append(path, Suffix...) 178 | if exists { 179 | path = append(path, obj.Id) 180 | } 181 | 182 | _, err := c.Communicate(method, path, nil, obj, nil) 183 | return err 184 | } 185 | -------------------------------------------------------------------------------- /integration/structs.go: -------------------------------------------------------------------------------- 1 | package integration 2 | 3 | type Integration struct { 4 | Id string `json:"id,omitempty"` 5 | Name string `json:"name"` 6 | IntegrationType string `json:"integrationType"` 7 | IntegrationConfig IntegrationConfig `json:"integrationConfig"` 8 | Description string `json:"description"` 9 | Enabled bool `json:"enabled"` 10 | CreatedBy string `json:"createdBy,omitempty"` 11 | CreatedTs int `json:"createdTs,omitempty"` 12 | LastModifiedBy string `json:"lastModifiedBy,omitempty"` 13 | LastModifiedTs int64 `json:"lastModifiedTs,omitempty"` 14 | Status string `json:"status,omitempty"` 15 | Reason *Reason `json:"reason"` 16 | Valid bool `json:"valid,omitempty"` 17 | AlertRules []AlertRule `json:"alertRules,omitempty"` 18 | } 19 | 20 | type IntegrationConfig struct { 21 | // Amazon SQS. 22 | QueueUrl string `json:"queueUrl,omitempty"` 23 | // RoleArn 24 | // ExternalId 25 | // AccessKey 26 | // SecretKey 27 | MoreInfo bool `json:"moreInfo,omitempty"` 28 | 29 | // Qualys. 30 | Login string `json:"login,omitempty"` 31 | BaseUrl string `json:"baseUrl,omitempty"` 32 | Password string `json:"password,omitempty"` 33 | 34 | // Service Now. 35 | HostUrl string `json:"hostUrl,omitempty"` 36 | // Login 37 | // Password 38 | Tables []map[string]bool `json:"tables,omitempty"` 39 | Version string `json:"version,omitempty"` 40 | 41 | // Webhook. 42 | Url string `json:"url,omitempty"` 43 | Headers []Header `json:"headers,omitempty"` 44 | 45 | // PagerDuty. 46 | IntegrationKey string `json:"integrationKey,omitempty"` 47 | AuthToken string `json:"authToken,omitempty"` 48 | 49 | // Slack 50 | WebHookUrl string `json:"webhookUrl,omitempty"` 51 | 52 | // Google CSCC 53 | SourceId string `json:"sourceId,omitempty"` 54 | OrgId string `json:"orgId,omitempty"` 55 | 56 | // Tenable 57 | AccessKey string `json:"accessKey,omitempty"` 58 | SecretKey string `json:"secretKey,omitempty"` 59 | 60 | // Cortex/demisto 61 | ApiKey string `json:"apiKey,omitempty"` 62 | // HostUrl 63 | // Version 64 | 65 | // Okta 66 | Domain string `json:"domain,omitempty"` 67 | ApiToken string `json:"apiToken,omitempty"` 68 | 69 | // Snowflake 70 | UserName string `json:"username,omitempty"` 71 | PipeName string `json:"pipename,omitempty"` 72 | PrivateKey string `json:"privateKey,omitempty"` 73 | PassPhrase string `json:"passphrase,omitempty"` 74 | StagingIntegrationID string `json:"stagingIntegrationId,omitempty"` 75 | // RollUpInterval 76 | 77 | // AWS security hub 78 | AccountId string `json:"accountId,omitempty"` 79 | Regions []Region `json:"regions,omitempty"` 80 | 81 | // Azure Service Bus Queue 82 | ConnectionString string `json:"connectionString,omitempty"` 83 | // AccountId 84 | // QueueUrl 85 | 86 | // Amazon S3 87 | S3Uri string `json:"s3Uri,omitempty"` 88 | Region string `json:"region,omitempty"` 89 | RoleArn string `json:"roleArn,omitempty"` 90 | ExternalId string `json:"externalId,omitempty"` 91 | RollUpInterval int `json:"rollUpInterval,omitempty"` 92 | 93 | // Splunk 94 | SourceType string `json:"sourceType,omitempty"` 95 | // Url 96 | // AuthToken 97 | } 98 | 99 | type Header struct { 100 | Key string `json:"key"` 101 | Value string `json:"value"` 102 | Secure bool `json:"secure"` 103 | ReadOnly bool `json:"readOnly"` 104 | } 105 | 106 | type Reason struct { 107 | LastUpdated int `json:"lastUpdated,omitempty"` 108 | ErrorType string `json:"errorType,omitempty"` 109 | Message string `json:"message,omitempty"` 110 | Details *Details `json:"details"` 111 | } 112 | 113 | type Details struct { 114 | StatusCode int `json:"statusCode,omitempty"` 115 | Subject string `json:"subject,omitempty"` 116 | Message string `json:"i18nKey,omitempty"` 117 | } 118 | 119 | type AlertRule struct { 120 | PolicyScanConfigId string `json:"policyScanConfigId"` 121 | Name string `json:"name"` 122 | } 123 | 124 | type Region struct { 125 | Name string `json:"name"` 126 | ApiIdentifier string `json:"apiIdentifier"` 127 | CloudType string `json:"cloudType"` 128 | SdkId string `json:"sdkId"` 129 | } 130 | 131 | type LicenseInfo struct { 132 | PrismaId string `json:"prismaId"` 133 | } 134 | -------------------------------------------------------------------------------- /interface.go: -------------------------------------------------------------------------------- 1 | package prismacloud 2 | 3 | type PrismaCloudClient interface { 4 | Initialize(string) error 5 | Authenticate() error 6 | Communicate(string, []string, interface{}, interface{}, interface{}) ([]byte, error) 7 | Log(string, string, ...interface{}) 8 | } 9 | -------------------------------------------------------------------------------- /ip-address/const.go: -------------------------------------------------------------------------------- 1 | package ip_address 2 | 3 | const ( 4 | singular = "ip-address" 5 | plural = "ip-addresses" 6 | ) 7 | 8 | var Suffix = []string{"ip_allow_list_login"} 9 | 10 | var statusSuffix = []string{"status"} 11 | -------------------------------------------------------------------------------- /ip-address/funcs.go: -------------------------------------------------------------------------------- 1 | package ip_address 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | pc "github.com/paloaltonetworks/prisma-cloud-go" 8 | ) 9 | 10 | // List lists accessible Login-Ip-Allow List. 11 | func List(c pc.PrismaCloudClient) ([]LoginIpAllow, error) { 12 | c.Log(pc.LogAction, "(get) list of %s", plural) 13 | 14 | var ans []LoginIpAllow 15 | if _, err := c.Communicate("GET", Suffix, nil, nil, &ans); err != nil { 16 | return nil, err 17 | } 18 | 19 | return ans, nil 20 | } 21 | 22 | // Get returns all information about an Login-Ip-Allow List using its ID. 23 | func Get(c pc.PrismaCloudClient, id string) (LoginIpAllow, error) { 24 | 25 | var ans LoginIpAllow 26 | path := make([]string, 0, len(Suffix)+1) 27 | path = append(path, Suffix...) 28 | path = append(path, id) 29 | 30 | c.Log(pc.LogAction, "(get) %s: %s path: %s", singular, id, path) 31 | _, err := c.Communicate("GET", path, nil, nil, &ans) 32 | return ans, err 33 | } 34 | 35 | // GetLoginIpStatus returns status information of Login ip status 36 | func GetLoginIpStatus(c pc.PrismaCloudClient) (LoginIpAllowStatus, error) { 37 | 38 | var ans LoginIpAllowStatus 39 | path := make([]string, 0, len(Suffix)+1) 40 | path = append(path, Suffix...) 41 | path = append(path, statusSuffix...) 42 | 43 | c.Log(pc.LogAction, "(get) ip allow list status path: %s", path) 44 | _, err := c.Communicate("GET", path, nil, nil, &ans) 45 | return ans, err 46 | } 47 | 48 | // Identify returns the ID for the given Login-Ip-Allow. 49 | func Identify(c pc.PrismaCloudClient, name string) (string, error) { 50 | c.Log(pc.LogAction, "(get) id for %s: %s api: %s", singular, name, Suffix) 51 | 52 | var ans []LoginIpAllow 53 | if _, err := c.Communicate("GET", Suffix, nil, nil, &ans); err != nil { 54 | return "", err 55 | } 56 | 57 | for _, o := range ans { 58 | if o.Name == name { 59 | return o.Id, nil 60 | } 61 | } 62 | 63 | return "", pc.ObjectNotFoundError 64 | } 65 | 66 | // Create makes a new account LoginIpAllow on the Prisma Cloud platform. 67 | func Create(c pc.PrismaCloudClient, loginIpAllow LoginIpAllow) error { 68 | return createUpdate(false, c, loginIpAllow) 69 | } 70 | 71 | // Update modifies information related to an existing account LoginIpAllow. 72 | func Update(c pc.PrismaCloudClient, loginIpAllow LoginIpAllow) error { 73 | return createUpdate(true, c, loginIpAllow) 74 | } 75 | 76 | // Delete removes an existing account LoginIpAllow using its ID. 77 | func Delete(c pc.PrismaCloudClient, id string) error { 78 | c.Log(pc.LogAction, "(delete) %s: %s", singular, id) 79 | 80 | path := make([]string, 0, len(Suffix)+1) 81 | path = append(path, Suffix...) 82 | path = append(path, id) 83 | 84 | _, err := c.Communicate("DELETE", path, nil, nil, nil) 85 | return err 86 | } 87 | 88 | func createUpdate(exists bool, c pc.PrismaCloudClient, loginIpAllow LoginIpAllow) error { 89 | var ( 90 | logMsg strings.Builder 91 | method string 92 | ) 93 | 94 | logMsg.Grow(30) 95 | logMsg.WriteString("(") 96 | if exists { 97 | logMsg.WriteString("update") 98 | method = "PUT" 99 | } else { 100 | logMsg.WriteString("create") 101 | method = "POST" 102 | } 103 | logMsg.WriteString(") ") 104 | 105 | logMsg.WriteString(singular) 106 | if exists { 107 | fmt.Fprintf(&logMsg, ": %s", loginIpAllow.Id) 108 | } 109 | 110 | c.Log(pc.LogAction, "Create Resource", logMsg.String()) 111 | 112 | path := make([]string, 0, len(Suffix)+2) 113 | path = append(path, Suffix...) 114 | if exists { 115 | path = append(path, loginIpAllow.Id) 116 | } 117 | 118 | _, err := c.Communicate(method, path, nil, loginIpAllow, nil) 119 | return err 120 | } 121 | 122 | func LoginIpStatusUpdate(c pc.PrismaCloudClient, loginIpAllowStatus LoginIpAllowStatus) error { 123 | var ( 124 | logMsg strings.Builder 125 | method string 126 | ) 127 | 128 | logMsg.Grow(30) 129 | logMsg.WriteString("(") 130 | 131 | logMsg.WriteString("update status") 132 | method = "PATCH" 133 | 134 | logMsg.WriteString(") ") 135 | 136 | c.Log(pc.LogAction, "trusted login ip", logMsg.String()) 137 | 138 | path := make([]string, 0, len(Suffix)+1) 139 | path = append(path, Suffix...) 140 | path = append(path, statusSuffix...) 141 | 142 | _, err := c.Communicate(method, path, nil, loginIpAllowStatus, nil) 143 | return err 144 | } 145 | -------------------------------------------------------------------------------- /ip-address/structs.go: -------------------------------------------------------------------------------- 1 | package ip_address 2 | 3 | type IdList struct { 4 | Id string `json:"id"` 5 | Name string `json:"name"` 6 | } 7 | 8 | type LoginIpAllow struct { 9 | Id string `json:"id"` 10 | Name string `json:"name"` 11 | Cidr []string `json:"cidr"` 12 | Description string `json:"description"` 13 | LastModifiedTs int `json:"lastModifiedTs"` 14 | } 15 | 16 | type LoginIpAllowStatus struct { 17 | Enabled bool `json:"enabled"` 18 | } 19 | -------------------------------------------------------------------------------- /notification-template/const.go: -------------------------------------------------------------------------------- 1 | package notification_template 2 | 3 | const ( 4 | singular = "notification-template" 5 | plural = "notification-templates" 6 | ) 7 | 8 | var Suffix1 = []string{"api", "v1", "tenant"} 9 | var Suffix2 = []string{"template"} 10 | var LicenseSuffix = []string{"license"} 11 | 12 | const ( 13 | Email = "email" 14 | Jira = "jira" 15 | ServiceNow = "service_now" 16 | 17 | ListType = "list" 18 | TextType = "text" 19 | ArrayType = "array" 20 | BoolType = "bool" 21 | IntegerType = "integer" 22 | ) 23 | -------------------------------------------------------------------------------- /notification-template/funcs.go: -------------------------------------------------------------------------------- 1 | package notification_template 2 | 3 | import ( 4 | "fmt" 5 | pc "github.com/paloaltonetworks/prisma-cloud-go" 6 | "strings" 7 | ) 8 | 9 | func List(c pc.PrismaCloudClient) ([]NotificationTemplate, error) { 10 | c.Log(pc.LogAction, "(get) list of %s", plural) 11 | 12 | var templates []NotificationTemplate 13 | path := make([]string, 0, len(Suffix1)+len(Suffix2)+1) 14 | path = append(path, Suffix1...) 15 | prismaId, err := GetPrismaId(c) 16 | if err != nil { 17 | return nil, nil 18 | } 19 | path = append(path, prismaId) 20 | path = append(path, Suffix2...) 21 | if _, err := c.Communicate("GET", path, nil, nil, &templates); err != nil { 22 | return nil, err 23 | } 24 | return templates, nil 25 | } 26 | 27 | // Get returns the NotificationTemplate. 28 | func Get(c pc.PrismaCloudClient, id string) (NotificationTemplate, error) { 29 | c.Log(pc.LogAction, "(get) %s id:%s", singular, id) 30 | path := make([]string, 0, len(Suffix1)+len(Suffix2)+1) 31 | path = append(path, Suffix1...) 32 | prismaId, err := GetPrismaId(c) 33 | if err != nil { 34 | return NotificationTemplate{}, nil 35 | } 36 | path = append(path, prismaId) 37 | path = append(path, Suffix2...) 38 | path = append(path, id) 39 | var template NotificationTemplate 40 | if _, err := c.Communicate("GET", path, nil, nil, &template); err != nil { 41 | return NotificationTemplate{}, nil 42 | } 43 | return template, nil 44 | } 45 | 46 | // Create adds a new NotificationTemplate. 47 | func Create(c pc.PrismaCloudClient, template NotificationTemplateRequest) (NotificationTemplate, error) { 48 | return createUpdate(false, c, template, "") 49 | } 50 | func Delete(c pc.PrismaCloudClient, id string) error { 51 | c.Log(pc.LogAction, "(delete) %s id:%s", singular, id) 52 | path := make([]string, 0, len(Suffix1)+len(Suffix2)+1) 53 | path = append(path, Suffix1...) 54 | 55 | prismaId, err := GetPrismaId(c) 56 | if err != nil { 57 | return nil 58 | } 59 | path = append(path, prismaId) 60 | path = append(path, Suffix2...) 61 | path = append(path, id) 62 | _, err = c.Communicate("GET", path, nil, nil, nil) 63 | 64 | if err != nil { 65 | return err 66 | } 67 | _, err = c.Communicate("DELETE", path, nil, nil, nil) 68 | if err != nil { 69 | return err 70 | 71 | } 72 | return err 73 | } 74 | 75 | // Update modifies the existing NotificationTemplate. 76 | func Update(c pc.PrismaCloudClient, template NotificationTemplateRequest, id string) (NotificationTemplate, error) { 77 | return createUpdate(true, c, template, id) 78 | } 79 | func createUpdate(exists bool, c pc.PrismaCloudClient, template NotificationTemplateRequest, id string) (NotificationTemplate, error) { 80 | var ( 81 | logMsg strings.Builder 82 | method string 83 | ) 84 | logMsg.Grow(30) 85 | logMsg.WriteString("(") 86 | if exists { 87 | logMsg.WriteString("update") 88 | method = "PATCH" 89 | } else { 90 | logMsg.WriteString("create") 91 | method = "POST" 92 | } 93 | logMsg.WriteString(") ") 94 | logMsg.WriteString(singular) 95 | if exists { 96 | fmt.Fprintf(&logMsg, ":%s", template.Name) 97 | } 98 | c.Log(pc.LogAction, logMsg.String()) 99 | 100 | path := make([]string, 0, len(Suffix1)+len(Suffix2)+1) 101 | path = append(path, Suffix1...) 102 | prismaId, err := GetPrismaId(c) 103 | if err != nil { 104 | return NotificationTemplate{}, nil 105 | } 106 | path = append(path, prismaId) 107 | path = append(path, Suffix2...) 108 | if exists { 109 | path = append(path, id) 110 | } 111 | var templateRes NotificationTemplate 112 | if exists { 113 | _, err = c.Communicate(method, path, nil, template, nil) 114 | } else { 115 | _, err = c.Communicate(method, path, nil, template, &templateRes) 116 | } 117 | return templateRes, err 118 | } 119 | 120 | func Identify(c pc.PrismaCloudClient, templateName string) (string, error) { 121 | c.Log(pc.LogAction, "(get) id for %s templateName:%s", singular, templateName) 122 | ans, err := List(c) 123 | if err != nil { 124 | return "", err 125 | } 126 | for _, o := range ans { 127 | if o.Name == templateName { 128 | return o.Id, nil 129 | } 130 | } 131 | return "", pc.ObjectNotFoundError 132 | } 133 | 134 | // GetPrismaId returns prisma id. 135 | func GetPrismaId(c pc.PrismaCloudClient) (string, error) { 136 | c.Log(pc.LogAction, "(get) prisma id") 137 | var ans LicenseInfo 138 | path := make([]string, 0, len(LicenseSuffix)+1) 139 | path = append(path, LicenseSuffix...) 140 | _, err := c.Communicate("GET", path, nil, nil, &ans) 141 | return ans.PrismaId, err 142 | } 143 | -------------------------------------------------------------------------------- /notification-template/structs.go: -------------------------------------------------------------------------------- 1 | package notification_template 2 | 3 | // To Create A new Template 4 | type NotificationTemplateRequest struct { 5 | IntegrationType string `json:"integrationType"` 6 | IntegrationId string `json:"integrationId,omitempty"` 7 | TemplateType string `json:"templateType,omitempty"` 8 | Enabled bool `json:"enabled,omitempty"` 9 | Name string `json:"name"` 10 | TemplateConfig TemplateConfigStruct `json:"templateConfig"` 11 | } 12 | 13 | type TemplateConfigStruct struct { 14 | Open []Config `json:"open,omitempty"` 15 | Resolved []Config `json:"resolved,omitempty"` 16 | Dismissed []Config `json:"dismissed,omitempty"` 17 | BasicConfig []Config `json:"basic_config,omitempty"` 18 | Snoozed []Config `json:"snoozed,omitempty"` 19 | } 20 | type Config struct { 21 | AliasField string `json:"aliasField,omitempty"` 22 | DisplayName string `json:"displayName,omitempty"` 23 | FieldName string `json:"fieldName,omitempty"` 24 | MaxLength int `json:"maxLength,omitempty"` 25 | Options []Option `json:"options"` 26 | RedlockMapping bool `json:"redlockMapping,omitempty"` 27 | Required bool `json:"required,omitempty"` 28 | Type string `json:"type,omitempty"` 29 | TypeaheadUri string `json:"typeaheadUri,omitempty"` 30 | Value string `json:"value,omitempty"` 31 | } 32 | 33 | type Option struct { 34 | Id string `json:"id,omitempty"` 35 | Key string `json:"key,omitempty"` 36 | Name string `json:"name,omitempty"` 37 | } 38 | 39 | type NotificationTemplate struct { 40 | Id string `json:"id"` 41 | IntegrationId string `json:"integrationId"` 42 | CreatedTs int64 `json:"createdTs"` 43 | IntegrationType string `json:"integrationType"` 44 | Name string `json:"name"` 45 | LastModifiedBy string `json:"lastModifiedBy"` 46 | LastModifiedTs int64 `json:"LastModifiedTs"` 47 | IntegrationName string `json:"integrationName"` 48 | CreatedBy string `json:"createdBy"` 49 | CustomerId int32 `json:"customerId"` 50 | Enabled bool `json:"enabled"` 51 | Module string `json:"module"` 52 | TemplateType string `json:"templateType"` 53 | TemplateConfig TemplateConfigStruct `json:"templateConfig"` 54 | } 55 | 56 | type LicenseInfo struct { 57 | PrismaId string `json:"prismaId"` 58 | } 59 | -------------------------------------------------------------------------------- /permission_group/const.go: -------------------------------------------------------------------------------- 1 | package permission_group 2 | 3 | var Suffix = []string{"authz", "v1", "permission_group"} 4 | 5 | const ( 6 | singular = "permission group" 7 | plural = "permission groups" 8 | ) 9 | 10 | // Valid values for permission_group.PermissionGroup. 11 | const ( 12 | TypeDefault = "Default" 13 | TypeCustom = "Custom" 14 | TypeInternal = "Internal" 15 | ) 16 | -------------------------------------------------------------------------------- /permission_group/funcs.go: -------------------------------------------------------------------------------- 1 | package permission_group 2 | 3 | import ( 4 | "fmt" 5 | "net/url" 6 | "strings" 7 | 8 | pc "github.com/paloaltonetworks/prisma-cloud-go" 9 | ) 10 | 11 | // Identify returns the ID associated with the specified user role name. 12 | func Identify(c pc.PrismaCloudClient, name string) (string, error) { 13 | c.Log(pc.LogAction, "(get) id for %s: %s", singular, name) 14 | 15 | path := make([]string, 0, len(Suffix)+1) 16 | path = append(path, Suffix...) 17 | 18 | var ans []NameId 19 | if _, err := c.Communicate("GET", path, nil, nil, &ans); err != nil { 20 | return "", err 21 | } 22 | 23 | for _, o := range ans { 24 | if o.Name == name { 25 | return o.Id, nil 26 | } 27 | } 28 | 29 | return "", pc.ObjectNotFoundError 30 | } 31 | func List(c pc.PrismaCloudClient) ([]PermissionGroup, error) { 32 | c.Log(pc.LogAction, "(get) list of %s", plural) 33 | 34 | var ans []PermissionGroup 35 | if _, err := c.Communicate("GET", Suffix, nil, nil, &ans); err != nil { 36 | return nil, err 37 | } 38 | 39 | return ans, nil 40 | } 41 | 42 | // Get returns all information about an user role using its ID. 43 | func Get(c pc.PrismaCloudClient, id string) (PermissionGroup, error) { 44 | c.Log(pc.LogAction, "(get) %s id:%s", singular, id) 45 | 46 | ans := PermissionGroup{} 47 | 48 | path := make([]string, 0, len(Suffix)+1) 49 | path = append(path, Suffix...) 50 | path = append(path, id) 51 | 52 | var query url.Values 53 | 54 | query = url.Values{} 55 | query.Add("includeAssociatedRoles", "true") 56 | if _, err := c.Communicate("GET", path, query, nil, &ans); err != nil { 57 | return ans, err 58 | } 59 | 60 | return ans, nil 61 | } 62 | 63 | // Create makes a new user role on the Prisma Cloud platform. 64 | func Create(c pc.PrismaCloudClient, obj PermissionGroup) error { 65 | return createUpdate(false, c, obj) 66 | } 67 | 68 | // Update modifies information related to an existing user role. 69 | func Update(c pc.PrismaCloudClient, obj PermissionGroup) error { 70 | return createUpdate(true, c, obj) 71 | } 72 | 73 | // Delete removes an existing user role using its ID. 74 | func Delete(c pc.PrismaCloudClient, id string) error { 75 | c.Log(pc.LogAction, "(delete) %s id:%s", singular, id) 76 | 77 | path := make([]string, 0, len(Suffix)+1) 78 | path = append(path, Suffix...) 79 | path = append(path, id) 80 | _, err := c.Communicate("DELETE", path, nil, nil, nil) 81 | return err 82 | } 83 | 84 | func createUpdate(exists bool, c pc.PrismaCloudClient, obj PermissionGroup) error { 85 | var ( 86 | logMsg strings.Builder 87 | method string 88 | ) 89 | 90 | logMsg.Grow(30) 91 | logMsg.WriteString("(") 92 | if exists { 93 | logMsg.WriteString("update") 94 | method = "PUT" 95 | } else { 96 | logMsg.WriteString("create") 97 | method = "POST" 98 | } 99 | logMsg.WriteString(") ") 100 | 101 | logMsg.WriteString(" ") 102 | logMsg.WriteString(singular) 103 | if exists { 104 | fmt.Fprintf(&logMsg, ": %s", obj.Id) 105 | } 106 | 107 | c.Log(pc.LogAction, logMsg.String()) 108 | 109 | path := make([]string, 0, len(Suffix)+1) 110 | path = append(path, Suffix...) 111 | if exists { 112 | path = append(path, obj.Id) 113 | } 114 | 115 | _, err := c.Communicate(method, path, nil, obj, nil) 116 | return err 117 | } 118 | -------------------------------------------------------------------------------- /permission_group/structs.go: -------------------------------------------------------------------------------- 1 | package permission_group 2 | 3 | type PermissionGroup struct { 4 | Id string `json:"id,omitempty"` 5 | Name string `json:"name"` 6 | Description string `json:"description,omitempty"` 7 | Type string `json:"type"` 8 | LastModifiedBy string `json:"lastModifiedBy,omitempty"` 9 | LastModifiedTs int64 `json:"lastModifiedTs,omitempty"` 10 | AssociatedRoles map[string]string `json:"associatedRoles"` 11 | Features []Features `json:"features"` 12 | AcceptAccountGroups bool `json:"acceptAccountGroups"` 13 | AcceptResourceLists bool `json:"acceptResourceLists"` 14 | AcceptCodeRepositories bool `json:"acceptCodeRepositories"` 15 | Custom bool `json:"custom"` 16 | Deleted bool `json:"deleted,omitempty"` 17 | } 18 | 19 | type Features struct { 20 | Operations Operations `json:"operations"` 21 | FeatureName string `json:"featureName"` 22 | } 23 | 24 | type NameId struct { 25 | Name string `json:"name"` 26 | Id string `json:"id"` 27 | } 28 | type Operations struct { 29 | CREATE bool `json:"CREATE"` 30 | READ bool `json:"READ"` 31 | UPDATE bool `json:"UPDATE"` 32 | DELETE bool `json:"DELETE"` 33 | } 34 | -------------------------------------------------------------------------------- /policy/const.go: -------------------------------------------------------------------------------- 1 | package policy 2 | 3 | const ( 4 | singular = "policy" 5 | plural = "policies" 6 | ) 7 | 8 | // Valid values for Policy.Rule.RuleType. 9 | const ( 10 | RuleTypeConfig = "Config" 11 | RuleTypeAuditEvent = "AuditEvent" 12 | RuleTypeNetwork = "Network" 13 | RuleTypeIAM = "IAM" 14 | RuleTypeAnomaly = "Anomaly" 15 | RuleTypeData = "DLP" 16 | RuleTypeNetworkConfig = "NetworkConfig" 17 | RuleAttackPath = "attack_path" 18 | ) 19 | 20 | // Valid values for Policy.PolicyType. 21 | const ( 22 | PolicyTypeConfig = "config" 23 | PolicyTypeAuditEvent = "audit_event" 24 | PolicyTypeNetwork = "network" 25 | PolicyTypeIAM = "iam" 26 | PolicyTypeAnomaly = "anomaly" 27 | PolicyTypeData = "data" 28 | PolicyTypeAttackPath = "attack_path" 29 | ) 30 | 31 | // Valid values for Policy.Rule.Severity. 32 | const ( 33 | SeverityLow = "low" 34 | SeverityMedium = "medium" 35 | SeverityHigh = "high" 36 | SeverityCritical = "critical" 37 | SeverityInformational = "informational" 38 | ) 39 | 40 | var Suffix = []string{"policy"} 41 | -------------------------------------------------------------------------------- /policy/funcs.go: -------------------------------------------------------------------------------- 1 | package policy 2 | 3 | import ( 4 | "fmt" 5 | "net/url" 6 | "strings" 7 | 8 | pc "github.com/paloaltonetworks/prisma-cloud-go" 9 | ) 10 | 11 | // List returns a list of available policies, both system default and custom. 12 | func List(c pc.PrismaCloudClient, query map[string]string) ([]Policy, error) { 13 | c.Log(pc.LogAction, "(get) list of %s", plural) 14 | 15 | qv := url.Values{} 16 | for k, v := range query { 17 | qv.Set(k, v) 18 | } 19 | 20 | var ans []Policy 21 | _, err := c.Communicate("GET", []string{"v2", "policy"}, qv, nil, &ans) 22 | 23 | return ans, err 24 | } 25 | 26 | // Identify returns the ID for the given policy name. 27 | func Identify(c pc.PrismaCloudClient, name string) (string, error) { 28 | c.Log(pc.LogAction, "(get) id for %s name:%s", singular, name) 29 | 30 | ans, err := List(c, map[string]string{"policy.name": name}) 31 | if err != nil { 32 | return "", err 33 | } 34 | 35 | switch len(ans) { 36 | case 0: 37 | return "", pc.ObjectNotFoundError 38 | case 1: 39 | return ans[0].PolicyId, nil 40 | } 41 | 42 | return "", fmt.Errorf("Got %d results back not 1", len(ans)) 43 | } 44 | 45 | // Get returns the policy that has the specified ID. 46 | func Get(c pc.PrismaCloudClient, id string) (Policy, error) { 47 | c.Log(pc.LogAction, "(get) %s id:%s", singular, id) 48 | 49 | path := make([]string, 0, len(Suffix)+1) 50 | path = append(path, Suffix...) 51 | path = append(path, id) 52 | 53 | var ans Policy 54 | _, err := c.Communicate("GET", path, nil, nil, &ans) 55 | 56 | return ans, err 57 | } 58 | 59 | // Create adds a new policy. 60 | func Create(c pc.PrismaCloudClient, policy Policy) error { 61 | return createUpdate(false, c, policy) 62 | } 63 | 64 | // Update modifies the existing policy. 65 | func Update(c pc.PrismaCloudClient, policy Policy) error { 66 | return createUpdate(true, c, policy) 67 | } 68 | 69 | // Delete removes a policy using its ID. 70 | func Delete(c pc.PrismaCloudClient, id string, policy Policy) error { 71 | c.Log(pc.LogAction, "(delete) %s id:%s", singular, id) 72 | path := make([]string, 0, len(Suffix)+1) 73 | path = append(path, Suffix...) 74 | path = append(path, id) 75 | _, err := c.Communicate("GET", path, nil, nil, nil) 76 | 77 | if err != nil { 78 | _, err := c.Communicate("DELETE", path, nil, nil, nil) 79 | return err 80 | } else if policy.Deleted == false { 81 | _, err := c.Communicate("DELETE", path, nil, nil, nil) 82 | return err 83 | } 84 | 85 | return err 86 | } 87 | 88 | func createUpdate(exists bool, c pc.PrismaCloudClient, policy Policy) error { 89 | var ( 90 | logMsg strings.Builder 91 | method string 92 | ) 93 | 94 | logMsg.Grow(30) 95 | logMsg.WriteString("(") 96 | if exists { 97 | logMsg.WriteString("update") 98 | method = "PUT" 99 | } else { 100 | logMsg.WriteString("create") 101 | method = "POST" 102 | } 103 | logMsg.WriteString(") ") 104 | 105 | logMsg.WriteString(singular) 106 | if exists { 107 | fmt.Fprintf(&logMsg, ":%s", policy.PolicyId) 108 | } 109 | 110 | c.Log(pc.LogAction, logMsg.String()) 111 | 112 | path := make([]string, 0, len(Suffix)+1) 113 | path = append(path, Suffix...) 114 | if exists { 115 | path = append(path, policy.PolicyId) 116 | } 117 | 118 | _, err := c.Communicate(method, path, nil, policy, nil) 119 | return err 120 | } 121 | -------------------------------------------------------------------------------- /policy/structs.go: -------------------------------------------------------------------------------- 1 | package policy 2 | 3 | type Policy struct { 4 | PolicyId string `json:"policyId,omitempty"` 5 | Name string `json:"name"` 6 | PolicyType string `json:"policyType"` 7 | PolicySubTypes []string `json:"policySubTypes,omitempty"` 8 | SystemDefault bool `json:"systemDefault,omitempty"` 9 | PolicyUpi string `json:"policyUpi,omitempty"` 10 | Description string `json:"description,omitempty"` 11 | Severity string `json:"severity"` 12 | Rule Rule `json:"rule"` 13 | Recommendation string `json:"recommendation"` 14 | CloudType string `json:"cloudType,omitempty"` 15 | ComplianceMetadata []ComplianceMetadata `json:"complianceMetadata"` 16 | Remediation Remediation `json:"remediation,omitempty"` 17 | Labels []string `json:"labels,omitempty"` // unordered 18 | Enabled bool `json:"enabled"` 19 | CreatedOn int `json:"createdOn,omitempty"` 20 | CreatedBy string `json:"createdBy,omitempty"` 21 | LastModifiedOn int `json:"lastModifiedOn,omitempty"` 22 | LastModifiedBy string `json:"lastModifiedBy,omitempty"` 23 | RuleLastModifiedOn int `json:"ruleLastModifiedOn,omitempty"` 24 | Overridden bool `json:"overridden,omitempty"` 25 | Deleted bool `json:"deleted,omitempty"` 26 | RestrictAlertDismissal bool `json:"restrictAlertDismissal,omitempty"` 27 | OpenAlertsCount int `json:"openAlertsCount,omitempty"` 28 | Owner string `json:"owner,omitempty"` 29 | PolicyMode string `json:"policyMode,omitempty"` 30 | PolicyCategory string `json:"policyCategory,omitempty"` 31 | PolicyClass string `json:"policyClass,omitempty"` 32 | Remediable bool `json:"remediable,omitempty"` 33 | } 34 | 35 | /* 36 | Rule is the rule object. 37 | 38 | Due to 05befc8b-c78a-45e9-98dc-c7fbaef580e7, criteria has to be 39 | an interface{}. 40 | */ 41 | type Rule struct { 42 | Name string `json:"name"` 43 | CloudType string `json:"cloudType,omitempty"` 44 | CloudAccount string `json:"cloudAccount,omitempty"` 45 | ResourceType string `json:"resourceType,omitempty"` 46 | ApiName string `json:"apiName,omitempty"` 47 | ResourceIdPath string `json:"resourceIdPath,omitempty"` 48 | Criteria interface{} `json:"criteria,omitempty"` 49 | DataCriteria DataCriteria `json:"dataCriteria,omitempty"` 50 | Children []Children `json:"children,omitempty"` 51 | Parameters map[string]string `json:"parameters"` 52 | Type string `json:"type"` 53 | } 54 | 55 | type ComplianceMetadata struct { 56 | StandardName string `json:"standardName,omitempty"` 57 | StandardDescription string `json:"standardDescription,omitempty"` 58 | RequirementId string `json:"requirementId,omitempty"` 59 | RequirementName string `json:"requirementName,omitempty"` 60 | RequirementDescription string `json:"requirementDescription,omitempty"` 61 | SectionId string `json:"sectionId,omitempty"` 62 | SectionDescription string `json:"sectionDescription,omitempty"` 63 | PolicyId string `json:"policyId,omitempty"` 64 | ComplianceId string `json:"complianceId,omitempty"` 65 | SectionLabel string `json:"sectionLabel,omitempty"` 66 | CustomAssigned bool `json:"customAssigned,omitempty"` 67 | } 68 | 69 | type Remediation struct { 70 | TemplateType string `json:"templateType,omitempty"` 71 | Description string `json:"description,omitempty"` 72 | CliScriptTemplate string `json:"cliScriptTemplate,omitempty"` 73 | CliScriptJsonSchema interface{} `json:"cliScriptJsonSchema,omitempty"` 74 | Actions []Action `json:"actions,omitempty"` 75 | } 76 | 77 | type Action struct { 78 | Operation string `json:"operation,oimtempty"` 79 | Payload string `json:"payload,omitempty"` 80 | } 81 | 82 | type DataCriteria struct { 83 | ClassificationResult string `json:"classificationResult,omitempty"` 84 | Exposure string `json:"exposure,omitempty"` 85 | Extension []string `json:"extension,omitempty"` 86 | } 87 | 88 | type Children struct { 89 | Criteria string `json:"criteria,omitempty"` 90 | Metadata Metadata `json:"metadata,omitempty"` 91 | Type string `json:"type,omitempty"` 92 | Recommendation string `json:"recommendation,omitempty"` 93 | } 94 | 95 | type Metadata struct { 96 | Code string `json:"code"` 97 | } 98 | -------------------------------------------------------------------------------- /report/const.go: -------------------------------------------------------------------------------- 1 | package report 2 | 3 | const ( 4 | singular = "report" 5 | plural = "reports" 6 | ) 7 | 8 | //Valid values for alert report types 9 | const ( 10 | CloudSecurityAssessment = "RIS" 11 | BusinessUnitReport = "INVENTORY_OVERVIEW" 12 | DetailedBusinessUnitReport = "INVENTORY_DETAIL" 13 | ) 14 | 15 | var alertReportTypes = []string{CloudSecurityAssessment, BusinessUnitReport, DetailedBusinessUnitReport} 16 | 17 | var Suffix = []string{"report"} 18 | -------------------------------------------------------------------------------- /report/funcs.go: -------------------------------------------------------------------------------- 1 | package report 2 | 3 | import ( 4 | "fmt" 5 | pc "github.com/paloaltonetworks/prisma-cloud-go" 6 | "net/url" 7 | "strings" 8 | ) 9 | 10 | // List returns a list of available alert and compliance reports 11 | func List(c pc.PrismaCloudClient) ([]Report, error) { 12 | c.Log(pc.LogAction, "(get) list of %s", plural) 13 | 14 | var alertReportList []Report 15 | qv := url.Values{} 16 | key := "report_view" 17 | for _, val := range alertReportTypes { 18 | qv.Add(key, val) 19 | } 20 | 21 | if _, err := c.Communicate("GET", Suffix, qv, nil, &alertReportList); err != nil { 22 | return nil, err 23 | } 24 | 25 | var complianceReportList []Report 26 | 27 | if _, err := c.Communicate("GET", Suffix, nil, nil, &complianceReportList); err != nil { 28 | return nil, err 29 | } 30 | 31 | var ans []Report 32 | ans = append(alertReportList, complianceReportList...) 33 | return ans, nil 34 | } 35 | 36 | // Identify returns the ID for the given report name. 37 | func Identify(c pc.PrismaCloudClient, name string) (string, error) { 38 | c.Log(pc.LogAction, "(get) id for %s name:%s", singular, name) 39 | 40 | list, err := List(c) 41 | if err != nil { 42 | return "", err 43 | } 44 | 45 | for _, o := range list { 46 | if o.Name == name { 47 | return o.Id, nil 48 | } 49 | } 50 | 51 | return "", pc.ObjectNotFoundError 52 | } 53 | 54 | // Get returns the report that has the specified ID. 55 | func Get(c pc.PrismaCloudClient, id string) (Report, error) { 56 | c.Log(pc.LogAction, "(get) %s id:%s", singular, id) 57 | 58 | path := make([]string, 0, len(Suffix)+1) 59 | path = append(path, Suffix...) 60 | path = append(path, id) 61 | 62 | var ans Report 63 | _, err := c.Communicate("GET", path, nil, nil, &ans) 64 | 65 | return ans, err 66 | } 67 | 68 | // Create adds a new report. 69 | func Create(c pc.PrismaCloudClient, report Report) error { 70 | return createUpdate(false, c, report) 71 | } 72 | 73 | // Update modifies the existing report. 74 | func Update(c pc.PrismaCloudClient, report Report) error { 75 | return createUpdate(true, c, report) 76 | } 77 | 78 | // Delete removes a report using its ID. 79 | func Delete(c pc.PrismaCloudClient, id string) error { 80 | c.Log(pc.LogAction, "(delete) %s id:%s", singular, id) 81 | 82 | path := make([]string, 0, len(Suffix)+1) 83 | path = append(path, Suffix...) 84 | path = append(path, id) 85 | _, err := c.Communicate("DELETE", path, nil, nil, nil) 86 | return err 87 | } 88 | 89 | func createUpdate(exists bool, c pc.PrismaCloudClient, report Report) error { 90 | var ( 91 | logMsg strings.Builder 92 | method string 93 | ) 94 | 95 | logMsg.Grow(30) 96 | logMsg.WriteString("(") 97 | if exists { 98 | logMsg.WriteString("update") 99 | method = "PUT" 100 | } else { 101 | logMsg.WriteString("create") 102 | method = "POST" 103 | } 104 | logMsg.WriteString(") ") 105 | 106 | logMsg.WriteString(singular) 107 | if exists { 108 | fmt.Fprintf(&logMsg, ":%s", report.Id) 109 | } 110 | 111 | c.Log(pc.LogAction, logMsg.String()) 112 | 113 | path := make([]string, 0, len(Suffix)+1) 114 | path = append(path, Suffix...) 115 | if exists { 116 | path = append(path, report.Id) 117 | } 118 | 119 | _, err := c.Communicate(method, path, nil, report, nil) 120 | return err 121 | } 122 | -------------------------------------------------------------------------------- /report/structs.go: -------------------------------------------------------------------------------- 1 | package report 2 | 3 | import "github.com/paloaltonetworks/prisma-cloud-go/timerange" 4 | 5 | type Report struct { 6 | Id string `json:"id,omitempty"` 7 | Name string `json:"name"` 8 | Type string `json:"type"` 9 | CloudType string `json:"cloudType"` 10 | ComplianceStandardId string `json:"complianceStandardId,omitempty"` 11 | Target Target `json:"target"` 12 | Status string `json:"status,omitempty"` 13 | CreatedOn int `json:"createdOn,omitempty"` 14 | CreatedBy string `json:"createdBy,omitempty"` 15 | LastModifiedOn int `json:"lastModifiedOn,omitempty"` 16 | LastModifiedBy string `json:"lastModifiedBy,omitempty"` 17 | NextSchedule int `json:"nextSchedule,omitempty"` 18 | LastScheduled int `json:"lastScheduled,omitempty"` 19 | TotalInstanceCount int `json:"totalInstanceCount,omitempty"` 20 | Counts Counts `json:"counts,omitempty"` 21 | } 22 | 23 | type Target struct { 24 | AccountGroups []string `json:"accountGroups"` 25 | Accounts []string `json:"accounts"` 26 | Regions []string `json:"regions"` 27 | ComplianceStandardIds []string `json:"complianceStandardIds"` 28 | CompressionEnabled bool `json:"compressionEnabled"` 29 | DownloadNow bool `json:"downloadNow"` 30 | NotifyTo []string `json:"notifyTo"` 31 | ResourceGroups []string `json:"resourceGroups"` 32 | Schedule string `json:"schedule"` 33 | ScheduleEnabled bool `json:"scheduleEnabled"` 34 | NotificationTemplateId string `json:"notificationTemplateId"` 35 | TimeRange timerange.TimeRange `json:"timeRange"` 36 | } 37 | 38 | type Counts struct { 39 | Failed int `json:"failed"` 40 | HighSeverityFailed int `json:"highSeverityFailed"` 41 | LowSeverityFailed int `json:"lowSeverityFailed"` 42 | MediumSeverityFailed int `json:"mediumSeverityFailed"` 43 | Passed int `json:"passed"` 44 | Total int `json:"total"` 45 | } 46 | -------------------------------------------------------------------------------- /resource-list/const.go: -------------------------------------------------------------------------------- 1 | package resource_list 2 | 3 | const ( 4 | singular = "resource-list" 5 | plural = "resource-lists" 6 | ) 7 | 8 | var Suffix = []string{"v1", "resource_list"} 9 | 10 | const ( 11 | TypeTags = "TAG" 12 | TypeAzureResourceGroups = "RESOURCE_GROUP" 13 | TypeComputeAccessGroups = "COMPUTE_ACCESS_GROUP" 14 | ) 15 | -------------------------------------------------------------------------------- /resource-list/funcs.go: -------------------------------------------------------------------------------- 1 | package resource_list 2 | 3 | import ( 4 | "fmt" 5 | pc "github.com/paloaltonetworks/prisma-cloud-go" 6 | "strings" 7 | ) 8 | 9 | func List(c pc.PrismaCloudClient) ([]ResourceList, error) { 10 | c.Log(pc.LogAction, "(get) list of %s", plural) 11 | 12 | var resourceLists []ResourceList 13 | path := make([]string, 0, len(Suffix)+1) 14 | path = append(path, Suffix...) 15 | if _, err := c.Communicate("GET", path, nil, nil, &resourceLists); err != nil { 16 | return nil, err 17 | } 18 | return resourceLists, nil 19 | } 20 | 21 | // Get returns the ResourceList. 22 | func Get(c pc.PrismaCloudClient, id string) (ResourceList, error) { 23 | c.Log(pc.LogAction, "(get) %s id:%s", singular, id) 24 | path := make([]string, 0, len(Suffix)+1) 25 | path = append(path, Suffix...) 26 | path = append(path, id) 27 | var template ResourceList 28 | if _, err := c.Communicate("GET", path, nil, nil, &template); err != nil { 29 | return ResourceList{}, err 30 | } 31 | return template, nil 32 | } 33 | 34 | // Create adds a new ResourceList. 35 | func Create(c pc.PrismaCloudClient, template ResourceListRequest) (ResourceList, error) { 36 | return createUpdate(false, c, template, "") 37 | } 38 | func Delete(c pc.PrismaCloudClient, id string) error { 39 | c.Log(pc.LogAction, "(delete) %s id:%s", singular, id) 40 | path := make([]string, 0, len(Suffix)+1) 41 | path = append(path, Suffix...) 42 | path = append(path, id) 43 | _, err := c.Communicate("GET", path, nil, nil, nil) 44 | if err != nil { 45 | return err 46 | } 47 | _, err = c.Communicate("DELETE", path, nil, nil, nil) 48 | if err != nil { 49 | return err 50 | 51 | } 52 | return err 53 | } 54 | 55 | // Update modifies the existing ResourceListTemplate. 56 | func Update(c pc.PrismaCloudClient, template ResourceListRequest, id string) (ResourceList, error) { 57 | return createUpdate(true, c, template, id) 58 | } 59 | func createUpdate(exists bool, c pc.PrismaCloudClient, template ResourceListRequest, id string) (ResourceList, error) { 60 | var ( 61 | logMsg strings.Builder 62 | method string 63 | ) 64 | logMsg.Grow(30) 65 | logMsg.WriteString("(") 66 | if exists { 67 | logMsg.WriteString("update") 68 | method = "PUT" 69 | } else { 70 | logMsg.WriteString("create") 71 | method = "POST" 72 | } 73 | logMsg.WriteString(") ") 74 | logMsg.WriteString(singular) 75 | if exists { 76 | fmt.Fprintf(&logMsg, ":%s", template.Name) 77 | } 78 | c.Log(pc.LogAction, logMsg.String()) 79 | 80 | path := make([]string, 0, len(Suffix)+1) 81 | path = append(path, Suffix...) 82 | if exists { 83 | path = append(path, id) 84 | } 85 | var templateRes ResourceList 86 | var err error 87 | if exists { 88 | _, err = c.Communicate(method, path, nil, template, nil) 89 | } else { 90 | _, err = c.Communicate(method, path, nil, template, &templateRes) 91 | } 92 | return templateRes, err 93 | } 94 | -------------------------------------------------------------------------------- /resource-list/structs.go: -------------------------------------------------------------------------------- 1 | package resource_list 2 | 3 | type ResourceList struct { 4 | Id string `json:"id,omitempty"` 5 | Description string `json:"description"` 6 | Name string `json:"name"` 7 | ResourceListType string `json:"resourceListType"` 8 | LastModifiedTs int64 `json:"lastModifiedTs"` 9 | LastModifiedBy string `json:"lastModifiedBy"` 10 | Members []interface{} `json:"members"` 11 | } 12 | 13 | // To Create A new ResourceList 14 | type ResourceListRequest struct { 15 | Name string `json:"name"` 16 | Description string `json:"description"` 17 | ResourceListType string `json:"resourceListType"` 18 | Members []interface{} `json:"members"` 19 | } 20 | -------------------------------------------------------------------------------- /rql/history/const.go: -------------------------------------------------------------------------------- 1 | package history 2 | 3 | // Valid values for the search filter when getting a list of RQL queries. 4 | const ( 5 | Recent = "recent" 6 | Saved = "saved" 7 | ) 8 | 9 | const ( 10 | singular = "historic rql query" 11 | plural = "historic rql queries" 12 | ) 13 | 14 | var Suffix = []string{"search", "history"} 15 | -------------------------------------------------------------------------------- /rql/history/funcs.go: -------------------------------------------------------------------------------- 1 | package history 2 | 3 | import ( 4 | "net/url" 5 | "strconv" 6 | 7 | pc "github.com/paloaltonetworks/prisma-cloud-go" 8 | ) 9 | 10 | // List lists saved or recent RQL search queries. 11 | func List(c pc.PrismaCloudClient, filter string, limit int) ([]NameId, error) { 12 | c.Log(pc.LogAction, "(get) list of %s", plural) 13 | 14 | query := url.Values{} 15 | query.Add("filter", filter) 16 | if limit != 0 { 17 | query.Add("limit", strconv.Itoa(limit)) 18 | } 19 | 20 | var ans []NameId 21 | _, err := c.Communicate("GET", Suffix, query, nil, &ans) 22 | 23 | return ans, err 24 | } 25 | 26 | // Identify returns the ID for the given account group. 27 | func Identify(c pc.PrismaCloudClient, name string) (string, error) { 28 | c.Log(pc.LogAction, "(get) id for %s: %s", singular, name) 29 | 30 | listing, err := List(c, Recent, 0) 31 | if err != nil { 32 | return "", err 33 | } 34 | 35 | for _, o := range listing { 36 | if o.Model.Name == name { 37 | return o.Model.Id, nil 38 | } 39 | } 40 | 41 | return "", pc.ObjectNotFoundError 42 | } 43 | 44 | // Get returns an historic RQL search query. 45 | func Get(c pc.PrismaCloudClient, id string) (Query, error) { 46 | c.Log(pc.LogAction, "(get) %s: %s", singular, id) 47 | 48 | var ans Query 49 | path := make([]string, 0, len(Suffix)+1) 50 | path = append(path, Suffix...) 51 | path = append(path, id) 52 | 53 | _, err := c.Communicate("GET", path, nil, nil, &ans) 54 | return ans, err 55 | } 56 | 57 | // Save saves an historic RQL search query to the saved searches list. 58 | func Save(c pc.PrismaCloudClient, req SavedSearch) (Query, error) { 59 | c.Log(pc.LogAction, "(create) saved search: %s", req.Id) 60 | 61 | var ans Query 62 | 63 | // Sanity check the time range. 64 | if err := req.TimeRange.SetType(); err != nil { 65 | return Query{}, err 66 | } 67 | 68 | path := make([]string, 0, len(Suffix)+1) 69 | path = append(path, Suffix...) 70 | path = append(path, req.Id) 71 | 72 | _, err := c.Communicate("POST", path, nil, req, &ans) 73 | return ans, err 74 | } 75 | 76 | // Delete removes an existing saved search query. 77 | func Delete(c pc.PrismaCloudClient, id string) error { 78 | c.Log(pc.LogAction, "(delete) %s: %s", singular, id) 79 | 80 | path := make([]string, 0, len(Suffix)+1) 81 | path = append(path, Suffix...) 82 | path = append(path, id) 83 | 84 | _, err := c.Communicate("DELETE", path, nil, nil, nil) 85 | return err 86 | } 87 | -------------------------------------------------------------------------------- /rql/history/structs.go: -------------------------------------------------------------------------------- 1 | package history 2 | 3 | import ( 4 | "github.com/paloaltonetworks/prisma-cloud-go/timerange" 5 | ) 6 | 7 | type NameId struct { 8 | CreatedBy string `json:"createdBy"` 9 | LastModifiedBy string `json:"lastModifiedBy"` 10 | Model Query `json:"searchModel"` 11 | } 12 | 13 | type Query struct { 14 | Id string `json:"id,omitempty"` 15 | Name string `json:"name"` 16 | Description string `json:"description"` 17 | SearchType string `json:"searchType"` 18 | CloudType string `json:"cloudType,omitempty"` 19 | Query string `json:"query"` 20 | Saved bool `json:"saved"` 21 | TimeRange timerange.TimeRange `json:"timeRange"` 22 | } 23 | 24 | // SavedSearch is to create a saved search. Always have Saved as false. 25 | type SavedSearch struct { 26 | Name string `json:"name"` 27 | Id string `json:"id"` 28 | TimeRange timerange.TimeRange `json:"timeRange"` 29 | Query string `json:"query"` 30 | Saved bool `json:"saved"` 31 | Description string `json:"description,omitempty"` 32 | CloudType string `json:"cloudType,omitempty"` 33 | } 34 | -------------------------------------------------------------------------------- /rql/search/const.go: -------------------------------------------------------------------------------- 1 | package search 2 | 3 | const ( 4 | configSingular = "config search" 5 | networkSingular = "network search" 6 | eventSingular = "event search" 7 | iamSingular = "iam search" 8 | assetSingular = "asset search" 9 | ) 10 | 11 | var BaseSuffix = []string{"search"} 12 | var ConfigSuffix = []string{"config"} 13 | var NetworkSuffix = []string{""} 14 | var EventSuffix = []string{"event"} 15 | var IamSuffix = []string{"api", "v1", "permission"} 16 | var AssetSuffix = []string{"api", "v1", "asset"} 17 | -------------------------------------------------------------------------------- /rql/search/funcs.go: -------------------------------------------------------------------------------- 1 | package search 2 | 3 | import ( 4 | _ "net/url" 5 | _ "strconv" 6 | 7 | pc "github.com/paloaltonetworks/prisma-cloud-go" 8 | ) 9 | 10 | // ConfigSearch performs a config RQL search. 11 | func ConfigSearch(c pc.PrismaCloudClient, req ConfigRequest) (ConfigResponse, error) { 12 | c.Log(pc.LogAction, "(get) performing %s", configSingular) 13 | 14 | var resp ConfigResponse 15 | 16 | // Sanity check the time range. 17 | if err := req.TimeRange.SetType(); err != nil { 18 | return resp, err 19 | } 20 | 21 | path := make([]string, 0, len(BaseSuffix)+len(ConfigSuffix)) 22 | path = append(path, BaseSuffix...) 23 | path = append(path, ConfigSuffix...) 24 | 25 | _, err := c.Communicate("POST", path, nil, req, &resp) 26 | return resp, err 27 | } 28 | 29 | // EventSearch performs a config RQL search. 30 | func EventSearch(c pc.PrismaCloudClient, req EventRequest) (EventResponse, error) { 31 | c.Log(pc.LogAction, "(get) performing %s", eventSingular) 32 | 33 | var resp EventResponse 34 | 35 | // Sanity check the time range. 36 | if err := req.TimeRange.SetType(); err != nil { 37 | return resp, err 38 | } 39 | 40 | path := make([]string, 0, len(BaseSuffix)+len(EventSuffix)) 41 | path = append(path, BaseSuffix...) 42 | path = append(path, EventSuffix...) 43 | 44 | _, err := c.Communicate("POST", path, nil, req, &resp) 45 | return resp, err 46 | } 47 | 48 | // NetworkSearch performs a config RQL search. 49 | func NetworkSearch(c pc.PrismaCloudClient, req NetworkRequest) (NetworkResponse, error) { 50 | c.Log(pc.LogAction, "(get) performing %s", networkSingular) 51 | 52 | var resp NetworkResponse 53 | 54 | // Sanity check the time range. 55 | if err := req.TimeRange.SetType(); err != nil { 56 | return resp, err 57 | } 58 | 59 | path := make([]string, 0, len(BaseSuffix)+len(NetworkSuffix)) 60 | path = append(path, BaseSuffix...) 61 | path = append(path, NetworkSuffix...) 62 | 63 | _, err := c.Communicate("POST", path, nil, req, &resp) 64 | return resp, err 65 | } 66 | 67 | // IamSearch performs an iam RQL search. 68 | func IamSearch(c pc.PrismaCloudClient, req IamRequest) (IamResponse, error) { 69 | c.Log(pc.LogAction, "(get) performing %s", iamSingular) 70 | 71 | var resp IamResponse 72 | 73 | path := make([]string, 0, len(IamSuffix)) 74 | path = append(path, IamSuffix...) 75 | 76 | _, err := c.Communicate("POST", path, nil, req, &resp) 77 | return resp, err 78 | } 79 | 80 | // AssetSearch performs an Asset RQL search 81 | func AssetSearch(c pc.PrismaCloudClient, req AssetRequest) (AssetResponse, error) { 82 | c.Log(pc.LogAction, "(get) performing %s", assetSingular) 83 | 84 | var resp AssetResponse 85 | 86 | path := make([]string, 0,len(BaseSuffix) + len(AssetSuffix)) 87 | path = append(path, BaseSuffix...) 88 | path = append(path, AssetSuffix...) 89 | 90 | _, err := c.Communicate("POST", path, nil, req, &resp) 91 | return resp, err 92 | } -------------------------------------------------------------------------------- /settings/enterprise/const.go: -------------------------------------------------------------------------------- 1 | package enterprise 2 | 3 | const ( 4 | singular = "enterprise settings" 5 | ) 6 | 7 | var Suffix = []string{"settings", "enterprise"} 8 | -------------------------------------------------------------------------------- /settings/enterprise/funcs.go: -------------------------------------------------------------------------------- 1 | package enterprise 2 | 3 | import ( 4 | pc "github.com/paloaltonetworks/prisma-cloud-go" 5 | ) 6 | 7 | // Get returns the enterprise settings for your tenant. 8 | func Get(c pc.PrismaCloudClient) (Config, error) { 9 | c.Log(pc.LogAction, "(get) %s", singular) 10 | 11 | path := Suffix[:] 12 | 13 | var ans Config 14 | _, err := c.Communicate("GET", path, nil, nil, &ans) 15 | return ans, err 16 | } 17 | 18 | // Update configures enterprise settings for your tenant. 19 | func Update(c pc.PrismaCloudClient, conf Config) error { 20 | c.Log(pc.LogAction, "(update) %s", singular) 21 | 22 | path := Suffix[:] 23 | _, err := c.Communicate("POST", path, nil, conf, nil) 24 | return err 25 | } 26 | -------------------------------------------------------------------------------- /settings/enterprise/structs.go: -------------------------------------------------------------------------------- 1 | package enterprise 2 | 3 | type Config struct { 4 | SessionTimeout int `json:"sessionTimeout,omitempty"` 5 | UserAttributionInNotification bool `json:"userAttributionInNotification"` 6 | RequireAlertDismissalNote bool `json:"requireAlertDismissalNote"` 7 | DefaultPoliciesEnabled map[string]bool `json:"defaultPoliciesEnabled"` 8 | ApplyDefaultPoliciesEnabled bool `json:"applyDefaultPoliciesEnabled"` 9 | AccessKeyMaxValidity int `json:"accessKeyMaxValidity"` 10 | AlarmEnabled bool `json:"alarmEnabled"` 11 | NamedUsersAccessKeysExpiryNotificationsEnabled bool `json:"namedUsersAccessKeysExpiryNotificationsEnabled"` 12 | ServiceUsersAccessKeysExpiryNotificationsEnabled bool `json:"serviceUsersAccessKeysExpiryNotificationsEnabled"` 13 | NotificationThresholdAccessKeysExpiry int `json:"notificationThresholdAccessKeysExpiry"` 14 | AuditLogSiemIntgrIds []string `json:"auditLogSiemIntgrIds"` 15 | AuditLogsEnabled bool `json:"auditLogsEnabled"` 16 | } 17 | -------------------------------------------------------------------------------- /structs.go: -------------------------------------------------------------------------------- 1 | package prismacloud 2 | 3 | type AuthResponse struct { 4 | Token string `json:"token"` 5 | Message string `json:"message"` 6 | Customers []AuthCustomer `json:"customerNames"` 7 | } 8 | 9 | type AuthCustomer struct { 10 | Name string `json:"customerName"` 11 | TosAccepted bool `json:"tosAccepted"` 12 | } 13 | -------------------------------------------------------------------------------- /timerange/const.go: -------------------------------------------------------------------------------- 1 | package timerange 2 | 3 | // These constants are implicitly used based on the time range value specified. 4 | const ( 5 | TypeRelative = "relative" 6 | TypeAbsolute = "absolute" 7 | TypeToNow = "to_now" 8 | ) 9 | 10 | // Valid values for Relative.Unit and ToNow.Unit. 11 | const ( 12 | Login = "login" // Valid for ToNow.Unit. 13 | Epoch = "epoch" // Valid for ToNow.Unit. 14 | Hour = "hour" // Valid for Relative.Unit. 15 | Day = "day" 16 | Week = "week" 17 | Month = "month" 18 | Year = "year" 19 | ) 20 | -------------------------------------------------------------------------------- /timerange/struct.go: -------------------------------------------------------------------------------- 1 | package timerange 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "strconv" 7 | ) 8 | 9 | // TimeRange is the time range model for Prisma Cloud. 10 | type TimeRange struct { 11 | Type string `json:"type"` 12 | Value interface{} `json:"value"` 13 | RelativeTimeType string `json:"relativeTimeType,omitempty"` 14 | } 15 | 16 | // SetType sets the time range type based on the value specified. 17 | func (o *TimeRange) SetType() error { 18 | switch v := o.Value.(type) { 19 | case Absolute: 20 | o.Type = TypeAbsolute 21 | case Relative: 22 | o.Type = TypeRelative 23 | case string: 24 | o.Type = TypeToNow 25 | case nil: 26 | return fmt.Errorf("time range must be specified") 27 | default: 28 | return fmt.Errorf("invalid time range type: %v", v) 29 | } 30 | 31 | return nil 32 | } 33 | 34 | // SetValue sets the Value based on what Type is specified. 35 | func (o *TimeRange) SetValue() error { 36 | var body []byte 37 | var err error 38 | 39 | if body, err = json.Marshal(o.Value); err != nil { 40 | return err 41 | } 42 | 43 | switch o.Type { 44 | case TypeAbsolute: 45 | v := Absolute{} 46 | if err = json.Unmarshal(body, &v); err != nil { 47 | return err 48 | } 49 | o.Value = v 50 | case TypeRelative: 51 | v := Relative{} 52 | if err = json.Unmarshal(body, &v); err != nil { 53 | return err 54 | } 55 | o.Value = v 56 | case TypeToNow: 57 | v := ToNow{} 58 | v.Unit, _ = strconv.Unquote(string(body)) 59 | o.Value = v 60 | } 61 | 62 | return nil 63 | } 64 | 65 | type Absolute struct { 66 | Start int `json:"startTime"` 67 | End int `json:"endTime"` 68 | } 69 | 70 | type Relative struct { 71 | Amount int `json:"amount"` 72 | Unit string `json:"unit"` 73 | } 74 | 75 | type ToNow struct { 76 | Unit string `json:"unit"` 77 | } 78 | -------------------------------------------------------------------------------- /trusted-alert-ip/const.go: -------------------------------------------------------------------------------- 1 | package trustedalertip 2 | 3 | const ( 4 | singular = "trusted alert ip" 5 | plural = "trusted alert ips" 6 | ) 7 | 8 | var Suffix = []string{"allow_list", "network"} 9 | -------------------------------------------------------------------------------- /trusted-alert-ip/funcs.go: -------------------------------------------------------------------------------- 1 | package trustedalertip 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | pc "github.com/paloaltonetworks/prisma-cloud-go" 8 | ) 9 | 10 | // Identify returns the ID for the given account group. 11 | func Identify(c pc.PrismaCloudClient, name string) (string, error) { 12 | c.Log(pc.LogAction, "(get) id for %s: %s", singular, name) 13 | 14 | listing, err := List(c) 15 | if err != nil { 16 | return "", err 17 | } 18 | 19 | for _, o := range listing { 20 | if o.Name == name { 21 | return o.UUID, nil 22 | } 23 | } 24 | 25 | return "", pc.ObjectNotFoundError 26 | } 27 | 28 | // List returns a list of available users and service accounts 29 | func List(c pc.PrismaCloudClient) ([]TrustedAlertIP, error) { 30 | c.Log(pc.LogAction, "(get) list of %s", plural) 31 | 32 | var ans []TrustedAlertIP 33 | if _, err := c.Communicate("GET", Suffix, nil, nil, &ans); err != nil { 34 | return nil, err 35 | } 36 | 37 | return ans, nil 38 | } 39 | 40 | func Get(c pc.PrismaCloudClient, id string) (TrustedAlertIP, error) { 41 | c.Log(pc.LogAction, "(get) %s id:%s", singular, id) 42 | 43 | var ans TrustedAlertIP 44 | 45 | path := make([]string, 0, len(Suffix)+1) 46 | path = append(path, Suffix...) 47 | path = append(path, id) 48 | 49 | _, err := c.Communicate("GET", path, nil, nil, &ans) 50 | 51 | return ans, err 52 | } 53 | 54 | func Create(c pc.PrismaCloudClient, trustedAlertIP TrustedAlertIP) ([]byte, error) { 55 | return createUpdate(false, c, trustedAlertIP) 56 | } 57 | 58 | func Update(c pc.PrismaCloudClient, trustedAlertIP TrustedAlertIP) ([]byte, error) { 59 | return createUpdate(true, c, trustedAlertIP) 60 | } 61 | 62 | func Delete(c pc.PrismaCloudClient, id string, uuid string) error { 63 | c.Log(pc.LogAction, "(delete) %s id:%s", singular, id) 64 | 65 | path := make([]string, 0, len(Suffix)+5) 66 | path = append(path, Suffix...) 67 | path = append(path, id) 68 | path = append(path, "cidr") 69 | path = append(path, uuid) 70 | _, err := c.Communicate("DELETE", path, nil, nil, nil) 71 | return err 72 | } 73 | 74 | func createUpdate(exists bool, c pc.PrismaCloudClient, trustedAlertIP TrustedAlertIP) ([]byte, error) { 75 | var ( 76 | logMsg strings.Builder 77 | method string 78 | ) 79 | 80 | logMsg.Grow(30) 81 | logMsg.WriteString("(") 82 | if exists { 83 | logMsg.WriteString("update") 84 | method = "PUT" 85 | } else { 86 | logMsg.WriteString("create") 87 | method = "POST" 88 | } 89 | logMsg.WriteString(") ") 90 | 91 | logMsg.WriteString(singular) 92 | if exists { 93 | fmt.Fprintf(&logMsg, ":%s", trustedAlertIP.UUID) 94 | } 95 | 96 | c.Log(pc.LogAction, logMsg.String()) 97 | 98 | path := make([]string, 0, len(Suffix)+1) 99 | path = append(path, Suffix...) 100 | 101 | response, err := c.Communicate(method, path, nil, trustedAlertIP, nil) 102 | return response, err 103 | } 104 | 105 | func CreateCIDR(c pc.PrismaCloudClient, trustedAlertIP CIDRS, id string) ([]byte, error) { 106 | var ( 107 | logMsg strings.Builder 108 | method string 109 | ) 110 | method = "POST" 111 | logMsg.Grow(30) 112 | logMsg.WriteString("(") 113 | logMsg.WriteString(method) 114 | logMsg.WriteString(") ") 115 | logMsg.WriteString(singular) 116 | 117 | c.Log(pc.LogAction, logMsg.String()) 118 | 119 | path := make([]string, 0, len(Suffix)+4) 120 | path = append(path, Suffix...) 121 | path = append(path, id) 122 | path = append(path, "cidr") 123 | response, err := c.Communicate(method, path, nil, trustedAlertIP, nil) 124 | return response, err 125 | } 126 | 127 | func UpdateCIDR(c pc.PrismaCloudClient, trustedAlertIP CIDRS, id string, uuid string) ([]byte, error) { 128 | var ( 129 | logMsg strings.Builder 130 | method string 131 | ) 132 | method = "PUT" 133 | 134 | c.Log(pc.LogAction, logMsg.String()) 135 | 136 | path := make([]string, 0, len(Suffix)+5) 137 | path = append(path, Suffix...) 138 | path = append(path, id) 139 | path = append(path, "cidr") 140 | path = append(path, uuid) 141 | response, err := c.Communicate(method, path, nil, trustedAlertIP, nil) 142 | return response, err 143 | } 144 | 145 | func DeleteCIDRFromTrustedAlertIp(c pc.PrismaCloudClient, id string, uuid string) ([]byte, error) { 146 | var ( 147 | logMsg strings.Builder 148 | method string 149 | ) 150 | method = "DELETE" 151 | 152 | c.Log(pc.LogAction, logMsg.String()) 153 | 154 | path := make([]string, 0, len(Suffix)+5) 155 | path = append(path, Suffix...) 156 | path = append(path, id) 157 | path = append(path, "cidr") 158 | path = append(path, uuid) 159 | response, err := c.Communicate(method, path, nil, nil, nil) 160 | return response, err 161 | } 162 | -------------------------------------------------------------------------------- /trusted-alert-ip/structs.go: -------------------------------------------------------------------------------- 1 | package trustedalertip 2 | 3 | type TrustedAlertIP struct { 4 | UUID string `json:"uuid"` 5 | Name string `json:"name"` 6 | CidrCount int `json:"cidrCount"` 7 | CIDRS []CIDRS `json:"cidrs"` 8 | } 9 | 10 | type CIDRS struct { 11 | CIDR string `json:"cidr"` 12 | UUID string `json:"uuid"` 13 | CreatedOn int `json:"createdOn"` 14 | Description string `json:"description"` 15 | } 16 | -------------------------------------------------------------------------------- /user/profile/const.go: -------------------------------------------------------------------------------- 1 | package profile 2 | 3 | const ( 4 | singular = "user profile" 5 | plural = "user profiles" 6 | ) 7 | 8 | // Valid values for Profile.AccountType. 9 | const ( 10 | TypeUserAccount = "USER_ACCOUNT" 11 | TypeServiceAccount = "SERVICE_ACCOUNT" 12 | ) 13 | 14 | var Suffix = []string{"v3", "user"} 15 | -------------------------------------------------------------------------------- /user/profile/funcs.go: -------------------------------------------------------------------------------- 1 | package profile 2 | 3 | import ( 4 | "fmt" 5 | "net/url" 6 | "strings" 7 | 8 | pc "github.com/paloaltonetworks/prisma-cloud-go" 9 | ) 10 | 11 | // List returns a list of available users and service accounts 12 | func List(c pc.PrismaCloudClient) ([]Profile, error) { 13 | c.Log(pc.LogAction, "(get) list of %s", plural) 14 | 15 | var ans []Profile 16 | if _, err := c.Communicate("GET", Suffix, nil, nil, &ans); err != nil { 17 | return nil, err 18 | } 19 | 20 | return ans, nil 21 | } 22 | 23 | // Get returns the user profile or service account profile that has the specified ID. 24 | func Get(c pc.PrismaCloudClient, id string) (Profile, error) { 25 | c.Log(pc.LogAction, "(get) %s id:%s", singular, id) 26 | 27 | var ans Profile 28 | 29 | list, err := List(c) 30 | if err != nil { 31 | return ans, err 32 | } 33 | 34 | for _, o := range list { 35 | if o.Username == id { 36 | return o, nil 37 | } 38 | } 39 | 40 | return ans, pc.ObjectNotFoundError 41 | } 42 | 43 | // Create adds a user profile or a service account profile. 44 | func Create(c pc.PrismaCloudClient, profile Profile) ([]byte, error) { 45 | return createUpdate(false, c, profile) 46 | } 47 | 48 | // Update modifies the existing user profile. 49 | func Update(c pc.PrismaCloudClient, profile Profile) ([]byte, error) { 50 | return createUpdate(true, c, profile) 51 | } 52 | 53 | // Delete removes a user profile or service account profile using its ID. 54 | func Delete(c pc.PrismaCloudClient, id string, accountType string) error { 55 | c.Log(pc.LogAction, "(delete) %s id:%s", singular, id) 56 | 57 | path := make([]string, 0, len(Suffix)) 58 | if accountType == TypeServiceAccount { 59 | path = append(path, Suffix[1], id) 60 | } else { 61 | path = append(path, Suffix[1], url.QueryEscape(id)) 62 | } 63 | 64 | _, err := c.Communicate("DELETE", path, nil, nil, nil) 65 | return err 66 | } 67 | 68 | func createUpdate(exists bool, c pc.PrismaCloudClient, profile Profile) ([]byte, error) { 69 | var ( 70 | logMsg strings.Builder 71 | method string 72 | ) 73 | 74 | logMsg.Grow(30) 75 | logMsg.WriteString("(") 76 | if exists { 77 | logMsg.WriteString("update") 78 | method = "PUT" 79 | } else { 80 | logMsg.WriteString("create") 81 | method = "POST" 82 | } 83 | logMsg.WriteString(") ") 84 | 85 | logMsg.WriteString(singular) 86 | if exists { 87 | fmt.Fprintf(&logMsg, ":%s", profile.Id) 88 | } 89 | 90 | c.Log(pc.LogAction, logMsg.String()) 91 | 92 | path := make([]string, 0, len(Suffix)+1) 93 | 94 | if exists { 95 | path = append(path, "v2", Suffix[1], url.QueryEscape(profile.Id)) 96 | } else { 97 | path = append(path, Suffix...) 98 | } 99 | 100 | response, err := c.Communicate(method, path, nil, profile, nil) 101 | return response, err 102 | } 103 | -------------------------------------------------------------------------------- /user/profile/structs.go: -------------------------------------------------------------------------------- 1 | package profile 2 | 3 | type Profile struct { 4 | Id string `json:"id,omitempty"` 5 | AccountType string `json:"type"` 6 | Username string `json:"username"` 7 | FirstName string `json:"firstName,omitempty"` 8 | LastName string `json:"lastName,omitempty"` 9 | DisplayName string `json:"displayName,omitempty"` 10 | Email string `json:"email,omitempty"` 11 | AccessKeysAllowed bool `json:"accessKeysAllowed"` 12 | AccessKeyExpiration int `json:"accessKeyExpiration,omitempty"` 13 | AccessKeyName string `json:"accessKeyName,omitempty"` 14 | DefaultRoleId string `json:"defaultRoleId"` 15 | EnableKeyExpiration bool `json:"enableKeyExpiration,omitempty"` 16 | RoleIds []string `json:"roleIds"` 17 | TimeZone string `json:"timeZone"` 18 | Enabled bool `json:"enabled"` 19 | LastLoginTs int `json:"lastLoginTs,omitempty"` 20 | LastModifiedBy string `json:"lastModifiedBy,omitempty"` 21 | LastModifiedTs int `json:"lastModifiedTs,omitempty"` 22 | AccessKeysCount int `json:"accessKeysCount,omitempty"` 23 | Roles []Role `json:"roles,omitempty"` 24 | } 25 | 26 | type AccessKeyResponse struct { 27 | AccessKeyId string `json:"id"` 28 | SecretKey string `json:"secretKey"` 29 | } 30 | 31 | type Role struct { 32 | RoleId string `json:"id"` 33 | Name string `json:"name"` 34 | OnlyAllowCIAccess bool `json:"onlyAllowCIAccess"` 35 | OnlyAllowComputeAccess bool `json:"onlyAllowComputeAccess"` 36 | OnlyAllowReadAccess bool `json:"onlyAllowReadAccess"` 37 | RoleType string `json:"type"` 38 | } 39 | -------------------------------------------------------------------------------- /user/role/const.go: -------------------------------------------------------------------------------- 1 | package role 2 | 3 | const ( 4 | singular = "user role" 5 | plural = "user roles" 6 | ) 7 | 8 | // Valid values for Role.RoleType. 9 | const ( 10 | TypeSystemAdmin = "System Admin" 11 | TypeAccountGroupAdmin = "Account Group Admin" 12 | TypeAccountGroupReadOnly = "Account Group Read Only" 13 | TypeCloudProvisioningAdmin = "Cloud Provisioning Admin" 14 | TypeAccountAndCloudProvisioningAdmin = "Account and Cloud Provisioning Admin" 15 | TypeBuildAndDeploySecurity = "Build and Deploy Security" 16 | TypeDeveloper = "Developer" 17 | TypeNetSecOps = "NetSecOps" 18 | ) 19 | 20 | var Suffix = []string{"user", "role"} 21 | -------------------------------------------------------------------------------- /user/role/funcs.go: -------------------------------------------------------------------------------- 1 | package role 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | pc "github.com/paloaltonetworks/prisma-cloud-go" 8 | ) 9 | 10 | // Identify returns the ID associated with the specified user role name. 11 | func Identify(c pc.PrismaCloudClient, name string) (string, error) { 12 | c.Log(pc.LogAction, "(get) id for %s: %s", singular, name) 13 | 14 | path := make([]string, 0, len(Suffix)+1) 15 | path = append(path, Suffix...) 16 | path = append(path, "name") 17 | 18 | var ans []NameId 19 | if _, err := c.Communicate("GET", path, nil, nil, &ans); err != nil { 20 | return "", err 21 | } 22 | 23 | for _, o := range ans { 24 | if o.Name == name { 25 | return o.Id, nil 26 | } 27 | } 28 | 29 | return "", pc.ObjectNotFoundError 30 | } 31 | 32 | // List returns the user roles. 33 | func List(c pc.PrismaCloudClient) ([]Role, error) { 34 | c.Log(pc.LogAction, "(get) list of %s", plural) 35 | 36 | var ans []Role 37 | if _, err := c.Communicate("GET", Suffix, nil, nil, &ans); err != nil { 38 | return nil, err 39 | } 40 | 41 | return ans, nil 42 | } 43 | 44 | // Get returns all information about an user role using its ID. 45 | func Get(c pc.PrismaCloudClient, id string) (Role, error) { 46 | c.Log(pc.LogAction, "(get) %s id:%s", singular, id) 47 | 48 | ans := Role{} 49 | 50 | path := make([]string, 0, len(Suffix)+1) 51 | path = append(path, Suffix...) 52 | path = append(path, id) 53 | 54 | if _, err := c.Communicate("GET", path, nil, nil, &ans); err != nil { 55 | return ans, err 56 | } 57 | 58 | return ans, nil 59 | } 60 | 61 | // Create makes a new user role on the Prisma Cloud platform. 62 | func Create(c pc.PrismaCloudClient, obj Role) error { 63 | return createUpdate(false, c, obj) 64 | } 65 | 66 | // Update modifies information related to an existing user role. 67 | func Update(c pc.PrismaCloudClient, obj Role) error { 68 | return createUpdate(true, c, obj) 69 | } 70 | 71 | // Delete removes an existing user role using its ID. 72 | func Delete(c pc.PrismaCloudClient, id string) error { 73 | c.Log(pc.LogAction, "(delete) %s id:%s", singular, id) 74 | 75 | path := make([]string, 0, len(Suffix)+1) 76 | path = append(path, Suffix...) 77 | path = append(path, id) 78 | _, err := c.Communicate("DELETE", path, nil, nil, nil) 79 | return err 80 | } 81 | 82 | func createUpdate(exists bool, c pc.PrismaCloudClient, obj Role) error { 83 | var ( 84 | logMsg strings.Builder 85 | method string 86 | ) 87 | 88 | logMsg.Grow(30) 89 | logMsg.WriteString("(") 90 | if exists { 91 | logMsg.WriteString("update") 92 | method = "PUT" 93 | } else { 94 | logMsg.WriteString("create") 95 | method = "POST" 96 | } 97 | logMsg.WriteString(") ") 98 | 99 | logMsg.WriteString(" ") 100 | logMsg.WriteString(singular) 101 | if exists { 102 | fmt.Fprintf(&logMsg, ": %s", obj.Id) 103 | } 104 | 105 | c.Log(pc.LogAction, logMsg.String()) 106 | 107 | path := make([]string, 0, len(Suffix)+1) 108 | path = append(path, Suffix...) 109 | if exists { 110 | path = append(path, obj.Id) 111 | } 112 | 113 | _, err := c.Communicate(method, path, nil, obj, nil) 114 | return err 115 | } 116 | -------------------------------------------------------------------------------- /user/role/structs.go: -------------------------------------------------------------------------------- 1 | package role 2 | 3 | type Role struct { 4 | Id string `json:"id,omitempty"` 5 | Name string `json:"name"` 6 | Description string `json:"description,omitempty"` 7 | RoleType string `json:"roleType"` 8 | LastModifiedBy string `json:"lastModifiedBy,omitempty"` 9 | LastModifiedTs int64 `json:"lastModifiedTs,omitempty"` 10 | AccountGroupIds []string `json:"accountGroupIds"` 11 | ResourceListIds []string `json:"resourceListIds"` 12 | CodeRepositoryIds []string `json:"codeRepositoryIds"` 13 | AssociatedUsers []string `json:"associatedUsers"` 14 | RestrictDismissalAccess bool `json:"restrictDismissalAccess"` 15 | AccountGroups []AccountGroup `json:"accountGroups,omitempty"` 16 | AdditionalAttributes AdditionalAttributes `json:"additionalAttributes"` 17 | } 18 | 19 | type AccountGroup struct { 20 | Id string `json:"id"` 21 | Name string `json:"name"` 22 | } 23 | 24 | type NameId struct { 25 | Name string `json:"name"` 26 | Id string `json:"id"` 27 | } 28 | 29 | type AdditionalAttributes struct { 30 | OnlyAllowCIAccess bool `json:"onlyAllowCIAccess"` 31 | OnlyAllowComputeAccess bool `json:"onlyAllowComputeAccess"` 32 | OnlyAllowReadAccess bool `json:"onlyAllowReadAccess"` 33 | HasDefenderPermissions bool `json:"hasDefenderPermissions"` 34 | } 35 | --------------------------------------------------------------------------------