From 221eaf17159d54fed609cd9c3120d9aa3a203b5f Mon Sep 17 00:00:00 2001 From: Christopher Geers Date: Fri, 2 Aug 2024 14:25:28 -0500 Subject: [PATCH 1/3] feat(onboarding): cloud ingestion assets --- .../data_source_sysdig_secure_onboarding.go | 62 +++++++++++++++++++ ...ta_source_sysdig_secure_onboarding_test.go | 24 +++++++ sysdig/internal/client/v2/onboarding.go | 16 +++++ sysdig/provider.go | 1 + .../docs/d/secure_cloud_ingestion_assets.md | 32 ++++++++++ 5 files changed, 135 insertions(+) create mode 100644 website/docs/d/secure_cloud_ingestion_assets.md diff --git a/sysdig/data_source_sysdig_secure_onboarding.go b/sysdig/data_source_sysdig_secure_onboarding.go index 4580f2fff..580d9e480 100644 --- a/sysdig/data_source_sysdig_secure_onboarding.go +++ b/sysdig/data_source_sysdig_secure_onboarding.go @@ -282,6 +282,68 @@ func dataSourceSysdigSecureAgentlessScanningAssetsRead(ctx context.Context, d *s return nil } +func dataSourceSysdigSecureCloudIngestionAssets() *schema.Resource { + timeout := 5 * time.Minute + + return &schema.Resource{ + ReadContext: dataSourceSysdigSecureCloudIngestionAssetsRead, + + Timeouts: &schema.ResourceTimeout{ + Read: schema.DefaultTimeout(timeout), + }, + + Schema: map[string]*schema.Schema{ + "aws": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "gcp": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + } +} + +// Retrieves the information of a resource form the file and loads it in Terraform +func dataSourceSysdigSecureCloudIngestionAssetsRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client, err := getSecureOnboardingClient(meta.(SysdigClients)) + if err != nil { + return diag.FromErr(err) + } + + assets, err := client.GetCloudIngestionAssetsSecure(ctx) + if err != nil { + return diag.FromErr(err) + } + + assetsAws, _ := assets["aws"].(map[string]interface{}) + assetsGcp, _ := assets["gcp"].(map[string]interface{}) + + d.SetId("cloudIngestionAssets") + err = d.Set("aws", map[string]interface{}{ + "eventBusARN": assetsAws["eventBusARN"], + }) + if err != nil { + return diag.FromErr(err) + } + err = d.Set("gcp", map[string]interface{}{ + "routingKey": assetsGcp["routingKey"], + "metadata": assetsGcp["metadata"], + }) + if err != nil { + return diag.FromErr(err) + } + + return nil +} + var matchFirstCap = regexp.MustCompile("(.)([A-Z][a-z]+)") var matchAllCap = regexp.MustCompile("([a-z0-9])([A-Z])") diff --git a/sysdig/data_source_sysdig_secure_onboarding_test.go b/sysdig/data_source_sysdig_secure_onboarding_test.go index bf0bb7726..73e99e56b 100644 --- a/sysdig/data_source_sysdig_secure_onboarding_test.go +++ b/sysdig/data_source_sysdig_secure_onboarding_test.go @@ -147,3 +147,27 @@ func TestAccAgentlessScanningAssetsDataSource(t *testing.T) { }, }) } + +func TestAccCloudIngestionAssetsDataSource(t *testing.T) { + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + if v := os.Getenv("SYSDIG_SECURE_API_TOKEN"); v == "" { + t.Fatal("SYSDIG_SECURE_API_TOKEN must be set for acceptance tests") + } + }, + ProviderFactories: map[string]func() (*schema.Provider, error){ + "sysdig": func() (*schema.Provider, error) { + return sysdig.Provider(), nil + }, + }, + Steps: []resource.TestStep{ + { + Config: `data "sysdig_secure_cloud_ingestion_assets" "assets" {}`, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("data.sysdig_secure_cloud_ingestion_assets.assets", "aws.%", "1"), + resource.TestCheckResourceAttr("data.sysdig_secure_cloud_ingestion_assets.assets", "gcp.%", "2"), + ), + }, + }, + }) +} diff --git a/sysdig/internal/client/v2/onboarding.go b/sysdig/internal/client/v2/onboarding.go index 0916ea2cf..4d51c7b59 100644 --- a/sysdig/internal/client/v2/onboarding.go +++ b/sysdig/internal/client/v2/onboarding.go @@ -11,6 +11,7 @@ const ( onboardingTrustedAzureAppPath = "%s/api/secure/onboarding/v2/trustedAzureApp?app=%s" onboardingTenantExternaIDPath = "%s/api/secure/onboarding/v2/externalID" onboardingAgentlessScanningAssetsPath = "%s/api/secure/onboarding/v2/agentlessScanningAssets" + onboardingCloudIngestionAssetsPath = "%s/api/secure/onboarding/v2/cloudIngestionAssets" ) type OnboardingSecureInterface interface { @@ -19,6 +20,7 @@ type OnboardingSecureInterface interface { GetTrustedAzureAppSecure(ctx context.Context, app string) (map[string]string, error) GetTenantExternalIDSecure(ctx context.Context) (string, error) GetAgentlessScanningAssetsSecure(ctx context.Context) (map[string]any, error) + GetCloudIngestionAssetsSecure(ctx context.Context) (map[string]any, error) } func (client *Client) GetTrustedCloudIdentitySecure(ctx context.Context, provider string) (string, error) { @@ -76,3 +78,17 @@ func (client *Client) GetAgentlessScanningAssetsSecure(ctx context.Context) (map return Unmarshal[map[string]interface{}](response.Body) } + +func (client *Client) GetCloudIngestionAssetsSecure(ctx context.Context) (map[string]interface{}, error) { + response, err := client.requester.Request(ctx, http.MethodGet, fmt.Sprintf(onboardingCloudIngestionAssetsPath, client.config.url), nil) + if err != nil { + return nil, err + } + defer response.Body.Close() + + if response.StatusCode != http.StatusOK { + return nil, client.ErrorFromResponse(response) + } + + return Unmarshal[map[string]interface{}](response.Body) +} diff --git a/sysdig/provider.go b/sysdig/provider.go index 60e354b8d..4c327135f 100644 --- a/sysdig/provider.go +++ b/sysdig/provider.go @@ -195,6 +195,7 @@ func (p *SysdigProvider) Provider() *schema.Provider { }, DataSourcesMap: map[string]*schema.Resource{ "sysdig_secure_agentless_scanning_assets": dataSourceSysdigSecureAgentlessScanningAssets(), + "sysdig_secure_cloud_ingestion_assets": dataSourceSysdigSecureCloudIngestionAssets(), "sysdig_secure_trusted_azure_app": dataSourceSysdigSecureTrustedAzureApp(), "sysdig_secure_trusted_cloud_identity": dataSourceSysdigSecureTrustedCloudIdentity(), "sysdig_secure_tenant_external_id": dataSourceSysdigSecureTenantExternalID(), diff --git a/website/docs/d/secure_cloud_ingestion_assets.md b/website/docs/d/secure_cloud_ingestion_assets.md new file mode 100644 index 000000000..394089836 --- /dev/null +++ b/website/docs/d/secure_cloud_ingestion_assets.md @@ -0,0 +1,32 @@ +--- +subcategory: "Sysdig Secure" +layout: "sysdig" +page_title: "Sysdig: sysdig_secure_cloud_ingestion_assets" +description: |- + Retrieves information about the Sysdig Secure Cloud Ingestion Assets +--- + +# Data Source: sysdig_secure_cloud_ingestion_assets + +Retrieves information about the Sysdig Secure Cloud Ingestion Assets + +-> **Note:** Sysdig Terraform Provider is under rapid development at this point. If you experience any issue or discrepancy while using it, please make sure you have the latest version. If the issue persists, or you have a Feature Request to support an additional set of resources, please open a [new issue](https://github.com/sysdiglabs/terraform-provider-sysdig/issues/new) in the GitHub repository. + +## Example Usage + +```terraform +data "sysdig_secure_cloud_ingestion_assets" "assets" {} +``` + +## Argument Reference + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `aws.eventBusARN` - AWS event bus from which Sysdig Cloud Ingestion operates + +* `gcp.routingKey` - GCP ingestion routing key + +* `gcp.metadata` - GCP ingestion metadata + From add997862c8e0fa66c166b72b9b019ee32f00fb5 Mon Sep 17 00:00:00 2001 From: Ravina Dhruve Date: Thu, 8 Aug 2024 10:44:08 -0700 Subject: [PATCH 2/3] Handle schema types for gcp and uncomment test assertions --- .../data_source_sysdig_secure_onboarding.go | 20 +++++++++------ ...ta_source_sysdig_secure_onboarding_test.go | 25 +++++++++++-------- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/sysdig/data_source_sysdig_secure_onboarding.go b/sysdig/data_source_sysdig_secure_onboarding.go index 580d9e480..d29743d2e 100644 --- a/sysdig/data_source_sysdig_secure_onboarding.go +++ b/sysdig/data_source_sysdig_secure_onboarding.go @@ -300,12 +300,13 @@ func dataSourceSysdigSecureCloudIngestionAssets() *schema.Resource { Type: schema.TypeString, }, }, - "gcp": { + "gcp_routing_key": { + Type: schema.TypeString, + Computed: true, + }, + "gcp_metadata": { Type: schema.TypeMap, Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, }, }, } @@ -333,10 +334,13 @@ func dataSourceSysdigSecureCloudIngestionAssetsRead(ctx context.Context, d *sche if err != nil { return diag.FromErr(err) } - err = d.Set("gcp", map[string]interface{}{ - "routingKey": assetsGcp["routingKey"], - "metadata": assetsGcp["metadata"], - }) + + err = d.Set("gcp_routing_key", assetsGcp["routingKey"]) + if err != nil { + return diag.FromErr(err) + } + + err = d.Set("gcp_metadata", assetsGcp["metadata"]) if err != nil { return diag.FromErr(err) } diff --git a/sysdig/data_source_sysdig_secure_onboarding_test.go b/sysdig/data_source_sysdig_secure_onboarding_test.go index 73e99e56b..ff730e124 100644 --- a/sysdig/data_source_sysdig_secure_onboarding_test.go +++ b/sysdig/data_source_sysdig_secure_onboarding_test.go @@ -75,27 +75,27 @@ func TestAccTrustedAzureAppDataSource(t *testing.T) { Config: `data "sysdig_secure_trusted_azure_app" "config_posture" { name = "config_posture" }`, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("data.sysdig_secure_trusted_azure_app.config_posture", "name", "config_posture"), - // resource.TestCheckResourceAttrSet("data.sysdig_secure_trusted_azure_app.config_posture", "application_id"), // uncomment to assert a non empty value - // resource.TestCheckResourceAttrSet("data.sysdig_secure_trusted_azure_app.config_posture", "tenant_id"), // uncomment to assert a non empty value - // resource.TestCheckResourceAttrSet("data.sysdig_secure_trusted_azure_app.config_posture", "service_principal_id"), // uncomment to assert a non empty value + resource.TestCheckResourceAttrSet("data.sysdig_secure_trusted_azure_app.config_posture", "application_id"), // uncomment to assert a non empty value + resource.TestCheckResourceAttrSet("data.sysdig_secure_trusted_azure_app.config_posture", "tenant_id"), // uncomment to assert a non empty value + resource.TestCheckResourceAttrSet("data.sysdig_secure_trusted_azure_app.config_posture", "service_principal_id"), // uncomment to assert a non empty value ), }, { Config: `data "sysdig_secure_trusted_azure_app" "onboarding" { name = "onboarding" }`, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("data.sysdig_secure_trusted_azure_app.onboarding", "name", "onboarding"), - // resource.TestCheckResourceAttrSet("data.sysdig_secure_trusted_azure_app.onboarding", "application_id"), // uncomment to assert a non empty value - // resource.TestCheckResourceAttrSet("data.sysdig_secure_trusted_azure_app.onboarding", "tenant_id"), // uncomment to assert a non empty value - // resource.TestCheckResourceAttrSet("data.sysdig_secure_trusted_azure_app.onboarding", "service_principal_id"), // uncomment to assert a non empty value + resource.TestCheckResourceAttrSet("data.sysdig_secure_trusted_azure_app.onboarding", "application_id"), // uncomment to assert a non empty value + resource.TestCheckResourceAttrSet("data.sysdig_secure_trusted_azure_app.onboarding", "tenant_id"), // uncomment to assert a non empty value + resource.TestCheckResourceAttrSet("data.sysdig_secure_trusted_azure_app.onboarding", "service_principal_id"), // uncomment to assert a non empty value ), }, { Config: `data "sysdig_secure_trusted_azure_app" "threat_detection" { name = "threat_detection" }`, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("data.sysdig_secure_trusted_azure_app.threat_detection", "name", "threat_detection"), - // resource.TestCheckResourceAttrSet("data.sysdig_secure_trusted_azure_app.threat_detection", "application_id"), // uncomment to assert a non empty value - // resource.TestCheckResourceAttrSet("data.sysdig_secure_trusted_azure_app.threat_detection", "tenant_id"), // uncomment to assert a non empty value - // resource.TestCheckResourceAttrSet("data.sysdig_secure_trusted_azure_app.threat_detection", "service_principal_id"), // uncomment to assert a non empty value + resource.TestCheckResourceAttrSet("data.sysdig_secure_trusted_azure_app.threat_detection", "application_id"), // uncomment to assert a non empty value + resource.TestCheckResourceAttrSet("data.sysdig_secure_trusted_azure_app.threat_detection", "tenant_id"), // uncomment to assert a non empty value + resource.TestCheckResourceAttrSet("data.sysdig_secure_trusted_azure_app.threat_detection", "service_principal_id"), // uncomment to assert a non empty value ), }, }, @@ -165,7 +165,12 @@ func TestAccCloudIngestionAssetsDataSource(t *testing.T) { Config: `data "sysdig_secure_cloud_ingestion_assets" "assets" {}`, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("data.sysdig_secure_cloud_ingestion_assets.assets", "aws.%", "1"), - resource.TestCheckResourceAttr("data.sysdig_secure_cloud_ingestion_assets.assets", "gcp.%", "2"), + resource.TestCheckResourceAttrSet("data.sysdig_secure_cloud_ingestion_assets.assets", "gcp_routing_key"), + + // metadata fields are opaque to api backend; cloudingestion controls what fields are passed + // asserts ingestionType and ingestionURL in metadata since it is required + resource.TestCheckResourceAttr("data.sysdig_secure_cloud_ingestion_assets.assets", "gcp_metadata.ingestionType", "gcp"), + resource.TestCheckResourceAttrSet("data.sysdig_secure_cloud_ingestion_assets.assets", "gcp_metadata.ingestionURL"), ), }, }, From 180d09e7097ae314dc4d9cfebc920e761d606e19 Mon Sep 17 00:00:00 2001 From: Ravina Dhruve Date: Thu, 8 Aug 2024 10:48:59 -0700 Subject: [PATCH 3/3] Update docs --- website/docs/d/secure_cloud_ingestion_assets.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/d/secure_cloud_ingestion_assets.md b/website/docs/d/secure_cloud_ingestion_assets.md index 394089836..7b8f9fefe 100644 --- a/website/docs/d/secure_cloud_ingestion_assets.md +++ b/website/docs/d/secure_cloud_ingestion_assets.md @@ -26,7 +26,7 @@ In addition to all arguments above, the following attributes are exported: * `aws.eventBusARN` - AWS event bus from which Sysdig Cloud Ingestion operates -* `gcp.routingKey` - GCP ingestion routing key +* `gcp_routing_key` - GCP ingestion routing key -* `gcp.metadata` - GCP ingestion metadata +* `gcp_metadata` - GCP ingestion metadata