Skip to content

Commit 3beb891

Browse files
authored
Merge pull request #12 from maxboynton/66-add-cloud-account
66 add cloud account
2 parents d10d573 + 94ae862 commit 3beb891

File tree

9 files changed

+722
-38
lines changed

9 files changed

+722
-38
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package account
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
7+
"github.com/PaloAltoNetworks/terraform-provider-prismacloudcompute/internal/api"
8+
"github.com/PaloAltoNetworks/terraform-provider-prismacloudcompute/internal/api/auth"
9+
)
10+
11+
const CloudScanRulesEndpoint = "api/v1/cloud-scan-rules"
12+
13+
// Serverless scan specs struct
14+
type ServerLessScanSpec struct {
15+
Enabled bool `json:"enabled,omitempty"`
16+
Cap int `json:"cap,omitempty"`
17+
ScanAllVersions bool `json:"scanAllVersions,omitempty"`
18+
ScanLayers bool `json:"scanLayers,omitempty"`
19+
}
20+
21+
type AgentlessScanSpec struct {
22+
Enabled bool `json:"enabled,omitempty"`
23+
HubAccount bool `json:"hubAccount,omitempty"`
24+
ConsoleAddr string `json:"consoleAddr,omitempty"`
25+
ScanNonRunning bool `json:"scanNonRunning,omitempty"`
26+
ProxyAddress string `json:"proxyAddress,omitempty"`
27+
ProxyCA string `json:"proxyCA,omitempty"`
28+
SkipPermissionsCheck bool `json:"skipPermissionsCheck,omitempty"`
29+
AutoScale bool `json:"autoScale,omitempty"`
30+
Scanners int `json:"scanners,omitempty"`
31+
SecurityGroup string `json:"securityGroup,omitempty"`
32+
SubNet string `json:"subnet,omitempty"`
33+
Regions []string `json:"regions,omitempty"`
34+
CustomTags []Tag `json:"customTags,omitempty"`
35+
IncludedTags []Tag `json:"includedTags,omitempty"`
36+
}
37+
38+
type Tag struct {
39+
Key string `json:"key,omitempty"`
40+
Value string `json:"value,omitempty"`
41+
}
42+
43+
type CloudScanRule struct {
44+
CredentialId string `json:"credentialId"`
45+
Credential auth.Credential `json:"credential,omitempty"`
46+
DiscoveryEnabled bool `json:"discoveryEnabled,omitempty"`
47+
ServerlessRadarEnabled bool `json:"serverlessRadarEnabled,omitempty"`
48+
VmTagsEnabled bool `json:"vmTagsEnabled,omitempty"`
49+
DiscoverAllFunctionVersions bool `json:"discoverAllFunctionVersions,omitempty"`
50+
ServerlessRadarCap int `json:"serverlessRadarCap,omitempty"`
51+
AgentlessScanSpec AgentlessScanSpec `json:"agentlessScanSpec,omitempty"`
52+
ServerlessScanSpec ServerLessScanSpec `json:"serverlessScanSpec,omitempty"`
53+
AwsRegionType string `json:"awsRegionType,omitempty"`
54+
}
55+
56+
// Get all cloud can rules
57+
func ListCloudScanRules(c api.Client) ([]CloudScanRule, error) {
58+
var ans []CloudScanRule
59+
if err := c.Request(http.MethodGet, CloudScanRulesEndpoint, nil, nil, &ans); err != nil {
60+
return nil, fmt.Errorf("error listing Cloud Scan Rules: %s", err)
61+
}
62+
return ans, nil
63+
}
64+
65+
// Get a specific cloud scan rule
66+
func GetCloudScanRule(c api.Client, name string) (*CloudScanRule, error) {
67+
var ans []CloudScanRule
68+
69+
if err := c.Request(http.MethodGet, CloudScanRulesEndpoint, map[string]string{"search": name}, nil, &ans); err != nil {
70+
return nil, fmt.Errorf("error searching Cloud Scan Rules: %s", err)
71+
}
72+
for _, val := range ans {
73+
if val.CredentialId == name {
74+
return &val, nil
75+
}
76+
}
77+
return nil, fmt.Errorf("Cloud Scan Rule '%s' not found", name)
78+
}
79+
80+
// Create/Update cloud scan rules
81+
func UpdateCloudScanRule(c api.Client, rule []CloudScanRule) error {
82+
return c.Request(http.MethodPut, CloudScanRulesEndpoint, nil, rule, nil)
83+
}
84+
85+
// Delete an existing cloud scan rule
86+
func DeleteCloudScanRule(c api.Client, name string) error {
87+
return c.Request(http.MethodDelete, fmt.Sprintf("%s/%s", CloudScanRulesEndpoint, name), nil, nil, nil)
88+
}

internal/api/auth/credential.go

Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,38 +9,25 @@ import (
99

1010
const CredentialsEndpoint = "api/v1/credentials"
1111

12-
// type Credential struct {
13-
// AccountGuid string `json:"accountGUID,omitempty"`
14-
// AccountId string `json:"accountID,omitempty"`
15-
// Description string `json:"description,omitempty"`
16-
// Name string `json:"_id,omitempty"`
17-
// Secret CredentialSecret `json:"secret,omitempty"`
18-
// Type string `json:"type,omitempty"`
19-
// UseAwsRole bool `json:"useAWSRole,omitempty"`
20-
// }
21-
22-
// type CredentialSecret struct {
23-
// Plain string `json:"plain,omitempty"`
24-
// }
25-
2612
type Credential struct {
27-
Id string `json:"_id,omitempty"`
28-
AccountGUID string `json:"accountGUID,omitempty"`
29-
AccountID string `json:"accountID,omitempty"`
30-
ApiToken Secret `json:"apiToken,omitempty"`
31-
CaCert string `json:"caCert,omitempty"`
32-
Created string `json:"created,omitempty"`
33-
Description string `json:"description,omitempty"`
34-
External bool `json:"external,omitempty"`
35-
LastModified string `json:"lastModified,omitempty"`
36-
Owner string `json:"owner,omitempty"`
37-
RoleArn string `json:"roleArn,omitempty"`
38-
Secret Secret `json:"secret,omitempty"`
39-
SkipVerify bool `json:"skipVerify,omitempty"`
40-
Tokens []TemporaryToken `json:"tokens,omitempty"`
41-
Type string `json:"type,omitempty"`
42-
Url string `json:"url,omitempty"`
43-
UseAWSRole bool `json:"useAWSRole,omitempty"`
13+
Id string `json:"_id,omitempty"`
14+
AccountGUID string `json:"accountGUID,omitempty"`
15+
AccountID string `json:"accountID,omitempty"`
16+
ApiToken Secret `json:"apiToken,omitempty"`
17+
CaCert string `json:"caCert,omitempty"`
18+
Created string `json:"created,omitempty"`
19+
Description string `json:"description,omitempty"`
20+
External bool `json:"external,omitempty"`
21+
LastModified string `json:"lastModified,omitempty"`
22+
Owner string `json:"owner,omitempty"`
23+
RoleArn string `json:"roleArn,omitempty"`
24+
Secret Secret `json:"secret,omitempty"`
25+
SkipVerify bool `json:"skipVerify,omitempty"`
26+
Tokens []TemporaryToken `json:"tokens,omitempty"`
27+
Type string `json:"type,omitempty"`
28+
Url string `json:"url,omitempty"`
29+
UseAWSRole bool `json:"useAWSRole,omitempty"`
30+
UseSTSRegionalEndpoint bool `json:"useSTSRegionalEndpoint,omitempty"`
4431
}
4532

4633
type Secret struct {

internal/api/client.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,26 @@ func (c *Client) Request(method, endpoint string, query, data, response interfac
100100
}
101101
req.Header.Set("Authorization", "Bearer "+c.JWT)
102102
req.Header.Set("Content-Type", "application/json")
103+
104+
// TODO: simplify logic
103105
if c.Config.Project != "" {
104106
queryParams := req.URL.Query()
105107
queryParams.Set("project", c.Config.Project)
108+
if query != nil {
109+
if queryMap, ok := query.(map[string]string); ok {
110+
for key, val := range queryMap {
111+
queryParams.Add(key, val)
112+
}
113+
}
114+
}
115+
req.URL.RawQuery = queryParams.Encode()
116+
} else if query != nil {
117+
queryParams := req.URL.Query()
118+
if queryMap, ok := query.(map[string]string); ok {
119+
for key, val := range queryMap {
120+
queryParams.Add(key, val)
121+
}
122+
}
106123
req.URL.RawQuery = queryParams.Encode()
107124
}
108125

internal/convert/cloudaccount.go

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
package convert
2+
3+
import (
4+
"github.com/PaloAltoNetworks/terraform-provider-prismacloudcompute/internal/api/account"
5+
"github.com/PaloAltoNetworks/terraform-provider-prismacloudcompute/internal/api/auth"
6+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
7+
)
8+
9+
func SchemaToCloudAccountCredential(d *schema.ResourceData) (auth.Credential, error) {
10+
var parsedCredential auth.Credential
11+
12+
if val, ok := d.GetOk("credential"); ok {
13+
for _, val := range val.([]interface{}) {
14+
parsedCredential.Id = val.(map[string]interface{})["name"].(string)
15+
parsedCredential.AccountID = val.(map[string]interface{})["account_id"].(string)
16+
if len(val.(map[string]interface{})["api_token"].([]interface{})) > 0 {
17+
parsedCredential.ApiToken = schemaToCredentialSecret(val.(map[string]interface{})["api_token"].([]interface{}))
18+
}
19+
parsedCredential.CaCert = val.(map[string]interface{})["ca_cert"].(string)
20+
parsedCredential.Description = val.(map[string]interface{})["description"].(string)
21+
parsedCredential.External = val.(map[string]interface{})["external"].(bool)
22+
//parsedCredential.AccountGUID = val.(map[string]interface{})["ibm_account_guide"].(string)
23+
parsedCredential.RoleArn = val.(map[string]interface{})["role_arn"].(string)
24+
parsedCredential.Id = val.(map[string]interface{})["id"].(string)
25+
if len(val.(map[string]interface{})["secret"].([]interface{})) > 0 {
26+
parsedCredential.Secret = schemaToCredentialSecret(val.(map[string]interface{})["secret"].([]interface{}))
27+
}
28+
parsedCredential.SkipVerify = val.(map[string]interface{})["skip_cert_verification"].(bool)
29+
parsedCredential.Type = val.(map[string]interface{})["type"].(string)
30+
parsedCredential.Url = val.(map[string]interface{})["url"].(string)
31+
parsedCredential.UseAWSRole = val.(map[string]interface{})["use_aws_role"].(bool)
32+
parsedCredential.UseSTSRegionalEndpoint = val.(map[string]interface{})["use_sts_regional_endpoint"].(bool)
33+
}
34+
}
35+
36+
return parsedCredential, nil
37+
}
38+
39+
func SchemaToCloudScanRule(d *schema.ResourceData) (account.CloudScanRule, error) {
40+
var parsedCloudScanRule account.CloudScanRule
41+
42+
if val, ok := d.GetOk("credential"); ok {
43+
parsedCloudScanRule.CredentialId = val.([]interface{})[0].(map[string]interface{})["name"].(string)
44+
}
45+
46+
if val, ok := d.GetOk("aws_region_type"); ok {
47+
parsedCloudScanRule.AwsRegionType = val.(string)
48+
}
49+
50+
if val, ok := d.GetOk("discovery_enabled"); ok {
51+
parsedCloudScanRule.DiscoveryEnabled = val.(bool)
52+
}
53+
54+
if val, ok := d.GetOk("serverless_radar_enabled"); ok {
55+
parsedCloudScanRule.ServerlessRadarEnabled = val.(bool)
56+
}
57+
58+
if val, ok := d.GetOk("vm_tags_enabled"); ok {
59+
parsedCloudScanRule.VmTagsEnabled = val.(bool)
60+
}
61+
62+
if val, ok := d.GetOk("discover_all_function_versions"); ok {
63+
parsedCloudScanRule.DiscoverAllFunctionVersions = val.(bool)
64+
}
65+
66+
if val, ok := d.GetOk("serverless_radar_cap"); ok {
67+
parsedCloudScanRule.ServerlessRadarCap = val.(int)
68+
}
69+
70+
if val, ok := d.GetOk("agentless_scan_spec"); ok {
71+
specs := val.(map[string]interface{})
72+
parsedCloudScanRule.AgentlessScanSpec.Enabled = specs["enabled"].(bool)
73+
parsedCloudScanRule.AgentlessScanSpec.HubAccount = specs["hub_account"].(bool)
74+
parsedCloudScanRule.AgentlessScanSpec.ConsoleAddr = specs["console_addr"].(string)
75+
parsedCloudScanRule.AgentlessScanSpec.ScanNonRunning = specs["scan_non_running"].(bool)
76+
parsedCloudScanRule.AgentlessScanSpec.ProxyAddress = specs["proxy_address"].(string)
77+
parsedCloudScanRule.AgentlessScanSpec.ProxyCA = specs["proxy_ca"].(string)
78+
parsedCloudScanRule.AgentlessScanSpec.SkipPermissionsCheck = specs["skip_permissions_check"].(bool)
79+
parsedCloudScanRule.AgentlessScanSpec.AutoScale = specs["auto_scale"].(bool)
80+
parsedCloudScanRule.AgentlessScanSpec.Scanners = specs["scanners"].(int)
81+
parsedCloudScanRule.AgentlessScanSpec.SecurityGroup = specs["security_group"].(string)
82+
parsedCloudScanRule.AgentlessScanSpec.SubNet = specs["subnet"].(string)
83+
parsedCloudScanRule.AgentlessScanSpec.Regions = SchemaToStringSlice(specs["regions"].([]interface{}))
84+
85+
presentCustomTags := specs["custom_tags"].([]interface{})
86+
parsedCustomTags := make([]account.Tag, 0, len(presentCustomTags))
87+
for _, val := range presentCustomTags {
88+
presentCustomTag := val.(map[string]interface{})
89+
parsedCustomTags = append(parsedCustomTags, account.Tag{
90+
Key: presentCustomTag["key"].(string),
91+
Value: presentCustomTag["value"].(string),
92+
})
93+
}
94+
parsedCloudScanRule.AgentlessScanSpec.CustomTags = parsedCustomTags
95+
96+
presentIncludedTags := specs["included_tags"].([]interface{})
97+
parsedIncludedTags := make([]account.Tag, 0, len(presentIncludedTags))
98+
for _, val := range presentIncludedTags {
99+
presentIncludedTag := val.(map[string]interface{})
100+
parsedIncludedTags = append(parsedIncludedTags, account.Tag{
101+
Key: presentIncludedTag["key"].(string),
102+
Value: presentIncludedTag["value"].(string),
103+
})
104+
}
105+
parsedCloudScanRule.AgentlessScanSpec.IncludedTags = parsedIncludedTags
106+
}
107+
108+
if val, ok := d.GetOk("aws_region_type"); ok {
109+
parsedCloudScanRule.AwsRegionType = val.(string)
110+
}
111+
112+
return parsedCloudScanRule, nil
113+
}
114+
115+
func ServerlessScanSpecToSchema(d *account.ServerLessScanSpec) []interface{} {
116+
ans := make([]interface{}, 0, 1)
117+
serverlessScanSpec := make(map[string]interface{})
118+
serverlessScanSpec["enabled"] = d.Enabled
119+
serverlessScanSpec["cap"] = d.Cap
120+
serverlessScanSpec["scan_all_versions"] = d.ScanAllVersions
121+
serverlessScanSpec["scan_layers"] = d.ScanLayers
122+
ans = append(ans, serverlessScanSpec)
123+
return ans
124+
}
125+
126+
func AgentlessScanSpecToSchema(d *account.AgentlessScanSpec) []interface{} {
127+
ans := make([]interface{}, 0, 1)
128+
agentlessScanSpec := make(map[string]interface{})
129+
agentlessScanSpec["enabled"] = d.Enabled
130+
agentlessScanSpec["hub_account"] = d.HubAccount
131+
agentlessScanSpec["console_addr"] = d.ConsoleAddr
132+
agentlessScanSpec["scan_non_running"] = d.ScanNonRunning
133+
agentlessScanSpec["proxy_address"] = d.ProxyAddress
134+
agentlessScanSpec["proxy_ca"] = d.ProxyCA
135+
agentlessScanSpec["skip_permissions_check"] = d.SkipPermissionsCheck
136+
agentlessScanSpec["auto_scale"] = d.AutoScale
137+
agentlessScanSpec["scanners"] = d.Scanners
138+
agentlessScanSpec["security_group"] = d.SecurityGroup
139+
agentlessScanSpec["subnet"] = d.SubNet
140+
agentlessScanSpec["regions"] = d.Regions
141+
ans = append(ans, agentlessScanSpec)
142+
return ans
143+
}
144+
145+
func CloudAccountCredentialToSchema(d auth.Credential) []interface{} {
146+
ans := make([]interface{}, 0, 1)
147+
credential := make(map[string]interface{})
148+
credential["id"] = d.Id
149+
credential["type"] = d.Type
150+
credential["account_id"] = d.AccountID
151+
credential["account_guid"] = d.AccountGUID
152+
credential["secret"] = CredentialSecretToSchema(d.Secret)
153+
credential["api_token"] = CredentialSecretToSchema(d.ApiToken)
154+
credential["use_aws_role"] = d.UseAWSRole
155+
ans = append(ans, credential)
156+
return ans
157+
}

internal/convert/credential.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ func SchemaToCredential(d *schema.ResourceData) (auth.Credential, error) {
4747
if val, ok := d.GetOk("use_aws_role"); ok {
4848
parsedCredential.UseAWSRole = val.(bool)
4949
}
50+
if val, ok := d.GetOk("use_sts_regional_endpoint"); ok {
51+
parsedCredential.UseSTSRegionalEndpoint = val.(bool)
52+
}
5053

5154
return parsedCredential, nil
5255
}

internal/provider/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ func Provider() *schema.Provider {
7676
"prismacloudcompute_role": resourceRbacRoles(),
7777
"prismacloudcompute_credential": resourceCredentials(),
7878
"prismacloudcompute_custom_compliance": resourceCustomCompliance(),
79+
"prismacloudcompute_cloud_account": resourceCloudAccount(),
7980
},
8081

8182
DataSourcesMap: map[string]*schema.Resource{

internal/provider/resource_alertprofile_test.go

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,7 @@ func testAccCheckAlertProfileDestroy(s *terraform.State) error {
9090
}
9191

9292
func testAccAlertProfileConfig(name string) string {
93-
return fmt.Sprintf(`
94-
provider "prismacloudcompute" {
95-
console_url = "https://us-east1.cloud.twistlock.com/us-1-111573457"
96-
username = "17aa4ffa-417c-4c5f-95c7-4cbae38bab53"
97-
password = "PvloZv58MSlPebdCECZ1HI5crPo="
98-
}
99-
93+
return fmt.Sprintf(`
10094
resource "prismacloudcompute_alertprofile" "test" {
10195
name = "%s"
10296
enable_immediate_vulnerabilities_alerts = false

0 commit comments

Comments
 (0)