Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions .envrc.template
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# prod/kubelab
# export SYSDIG_SECURE_URL=https://secure.sysdig.com

# credentials
export SYSDIG_SECURE_API_TOKEN=
export SYSDIG_MONITOR_API_TOKEN=

# export SYSDIG_SECURE_URL=https://secure.sysdig.com

# whether to run local acc test
export TF_ACC=false

# terraform log level
export TF_LOG=DEBUG
78 changes: 30 additions & 48 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,31 @@
<a href="https://terraform.io">
<img src="https://raw.githubusercontent.com/hashicorp/terraform-provider-aws/main/.github/terraform_logo.svg" alt="Terraform logo" title="Terraform" align="right" height="50" />
<img src="https://raw.githubusercontent.com/hashicorp/terraform-provider-aws/main/.github/terraform_logo.svg" alt="Terraform logo" title="Terraform" height="50" />
</a>


# Terraform Provider for Sysdig


- **[Terraform Registry - Sysdig Provider Docs](https://registry.terraform.io/providers/sysdiglabs/sysdig/latest/docs)**
- [Blog on how to use this provider with Sysdig Secure](https://sysdig.com/blog/using-terraform-for-container-security-as-code/)
- Terraform
- Website https://www.terraform.io
- Mailing list on [Google Groups](http://groups.google.com/group/terraform-tool)
- [![Gitter chat](https://badges.gitter.im/hashicorp-terraform/Lobby.png)](https://gitter.im/hashicorp-terraform/Lobby)


# Contribute
## Contribute

- [Initial Setup](#initial-setup)
- [Requirements](#requirements)
- [Develop](#develop)
- [Compile](#compile)
- [Test](#tests)
- [Install](#install-local)
- [Proposing PR's](#proposing-prs)
- [Release](#release)

## Initial Setup

### Building

#### Requirements
## Requirements

- [Terraform](https://www.terraform.io/downloads.html) > 0.12.x
- [Go](https://golang.org/doc/install) > Go version specified in [go.mod](./go.mod#L3)
- Correctly setup a [GOPATH](http://golang.org/doc/code.html#GOPATH), as well as adding `$GOPATH/bin` to your `$PATH`.

### Develop
## Develop

First **clone** source repository to: `$GOPATH/src/github.com/draios/terraform-provider-sysdig`

Expand All @@ -40,37 +35,36 @@ $ cd terraform-provider-sysdig
$ make build
```

### Compile
If you're a rookie, check [Official Terraform Provider development guides](https://developer.hashicorp.com/terraform/plugin/frameworkO)

### Creating new resource / data sources

TL;DR;
- Create the resource/data source item
- Add the created item into the `provider.go` resource or datasource map with its wiring
- With its [acceptance **test**](#tests)
- Add its **documentation** page on `./website/docs/`

## Compile

To **compile** the provider, run `make build`. This will build the provider and put the provider binary in the `$GOPATH/bin` directory.

```sh
$ make build
...
$ $GOPATH/bin/terraform-provider-sysdig
...
```

### Tests
In order to **test** the provider, you can simply run `make test`.
## Tests

```sh
$ make test
```
In order to **test** the provider, you can simply run `make test` to run unit-tests.
For acceptance tests, you can run `make testacc`, but note that
- Sysdig Montir and/or Secure credentials are required, check [`/.envrc.template`](https://github.com/sysdiglabs/terraform-provider-sysdig/blob/master/.envrc.template)
- **acceptance tests rely on the creation of real infrastructure**, you should execute them in an environment where you can remove the resources easily.

### Acceptance Tests
If you're a rookie, check [Terraform acceptance test guidelines](https://developer.hashicorp.com/terraform/plugin/testing)

If you want to execute the **acceptance tests**, you can run `make testacc`.
- Follow [Terraform acceptance test guideliness](https://www.terraform.io/plugin/sdkv2/testing/acceptance-tests)
- Please note that you need a token for Sysdig Monitor and another one for Sysdig Secure, and since the **acceptance tests create real infrastructure**
you should execute them in an environment where you can remove the resources easily.
- Acceptance tests are launched in [Sysdig production `+kubelab` test environment](https://github.com/sysdiglabs/terraform-provider-sysdig/blob/master/.github/workflows/ci-pull-request.yml#L82-L83)

```sh
$ make testacc
```

### Install (local)
## Install (local)
To use the local provider you just built, follow the instructions to [**install** it as a plugin.](https://www.terraform.io/docs/plugins/basics.html#installing-a-plugin) in your machine with:

```sh
Expand Down Expand Up @@ -100,20 +94,6 @@ To uninstall the plugin:
$ make uninstall
```

### Creating new resource / data sources

TL;DR;
- Create the resource/data source item
- Add the created item into the `provider.go` resource or datasource map with its wiring
- With its [acceptance **test**](#acceptance-tests)
- Add its **documentation** page on `./website/docs/`


Interesting resources
- https://www.terraform.io/plugin
- https://www.hashicorp.com/blog/testing-hashicorp-terraform


## Proposing PR's

* if it's your first time, validate you're taking into account every aspect of the [`./github/pull_request_template`](.github/pull_request_template.md)
Expand All @@ -122,7 +102,7 @@ Interesting resources
- You can work on this before even pushing to remote, using [**pre-commit**](https://pre-commit.com) plugin

* for the PR title use [conventional commit format](https://www.conventionalcommits.org/en/v1.0.0/) so when the branch is squashed to main branch it follows a convention
* for Acceptance Tests `testacc` some credentials are required, check [`/.envrc.template`](https://github.com/sysdiglabs/terraform-provider-sysdig/blob/master/.envrc.template)
* acceptance tests are launched in [Sysdig production `+kubelab` test environment](https://github.com/sysdiglabs/terraform-provider-sysdig/blob/master/.github/workflows/ci-pull-request.yml#L82-L83)


## Release
Expand All @@ -135,6 +115,8 @@ github/workflows/release.yml`](https://github.com/sysdiglabs/terraform-provider-
* Review Released Draft Note, and make it as clear as possible.
* Notify Sysdig teams on our internal #release-announcements slack channel and optionally in #terraform-provider

<br/><br/>

Mange takk!

![giphy](https://user-images.githubusercontent.com/1073243/200767344-7435f322-24c0-44d2-ac56-468791c84ca5.gif)
Expand Down
18 changes: 10 additions & 8 deletions sysdig/resource_sysdig_secure_cloud_auth_account.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,20 @@ import (
"strings"
"time"

v2 "github.com/draios/terraform-provider-sysdig/sysdig/internal/client/v2"
cloudauth "github.com/draios/terraform-provider-sysdig/sysdig/internal/client/v2/cloudauth/go"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/reflect/protoreflect"

v2 "github.com/draios/terraform-provider-sysdig/sysdig/internal/client/v2"
cloudauth "github.com/draios/terraform-provider-sysdig/sysdig/internal/client/v2/cloudauth/go"
)

func resourceSysdigSecureCloudauthAccount() *schema.Resource {
timeout := 5 * time.Minute

var accountFeature = &schema.Resource{
accountFeature := &schema.Resource{
Schema: map[string]*schema.Schema{
SchemaType: {
Type: schema.TypeString,
Expand All @@ -43,7 +44,7 @@ func resourceSysdigSecureCloudauthAccount() *schema.Resource {
},
}

var accountFeatures = &schema.Resource{
accountFeatures := &schema.Resource{
Schema: map[string]*schema.Schema{
SchemaSecureConfigPosture: {
Type: schema.TypeSet,
Expand Down Expand Up @@ -73,7 +74,7 @@ func resourceSysdigSecureCloudauthAccount() *schema.Resource {
},
}

var accountComponents = &schema.Resource{
accountComponents := &schema.Resource{
Schema: map[string]*schema.Schema{
SchemaType: {
Type: schema.TypeString,
Expand Down Expand Up @@ -259,7 +260,6 @@ func resourceSysdigSecureCloudauthAccountDelete(ctx context.Context, data *schem
}

errStatus, err := client.DeleteCloudauthAccountSecure(ctx, data.Id())

if err != nil {
if strings.Contains(errStatus, "404") {
return nil
Expand Down Expand Up @@ -515,7 +515,7 @@ func componentsToResourceData(components []*cloudauth.AccountComponent) []map[st
case cloudauth.Component_COMPONENT_SERVICE_PRINCIPAL:
// XXX: handle GCP specially because keys are base64 encoded
if component.GetServicePrincipalMetadata().GetGcp() != nil {
gcpKeyBytes := []byte{}
var gcpKeyBytes []byte
if component.GetServicePrincipalMetadata().GetGcp().GetKey() != nil {
var err error
gcpKeyBytes, err = protojson.MarshalOptions{UseProtoNames: true}.Marshal(component.GetServicePrincipalMetadata().GetGcp().GetKey())
Expand Down Expand Up @@ -558,10 +558,12 @@ func componentsToResourceData(components []*cloudauth.AccountComponent) []map[st

// internal type redefintion for GCP service principals.
// This exists because in terraform, the key is originally provided in the form of a base64 encoded json string

// note; caution with order of fields, they have to go in alphabetical ASC so that the json marshalled on the tf read phase produces no drift https://github.com/golang/go/issues/27179
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @cgeers just so you are aware of this.
for me it's ok to merge with this

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still scratching my head on they why here, but I'm willing to accept it as a benign change that spoon feeds our tf tests

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

haha, yeah... if you want to dig more into the issue feel free to do so, but let's agree on some criteria to accept this PR and unblock us; you can work on digging more anytime later.

i was there for couple of days and i'm ok letting it go...
gotta say though, i'm not expert on go, neither the json libraries. maybe you do see some other option

type internalServicePrincipalMetadata_GCP struct {
Email string `json:"email,omitempty"`
Key string `json:"key,omitempty"` // base64 encoded
WorkloadIdentityFederation *cloudauth.ServicePrincipalMetadata_GCP_WorkloadIdentityFederation `json:"workload_identity_federation,omitempty"`
Email string `json:"email,omitempty"`
}
type internalServicePrincipalMetadata struct {
Gcp *internalServicePrincipalMetadata_GCP `json:"gcp,omitempty"`
Expand Down
137 changes: 137 additions & 0 deletions sysdig/resource_sysdig_secure_cloud_auth_account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -441,3 +441,140 @@ func TestAccAWSSecureCloudAccountFCCSPM(t *testing.T) {
},
})
}

func TestGCPAgentlesScanningOnboarding(t *testing.T) {
rText := func() string { return acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum) }
accID := rText()
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: fmt.Sprintf(`
resource "sysdig_secure_cloud_auth_account" "gcp-agentless-scanning" {
provider_id = "gcp-agentless-test-%s"
provider_type = "PROVIDER_GCP"
enabled = true
feature {
secure_agentless_scanning {
enabled = true
components = ["COMPONENT_SERVICE_PRINCIPAL/secure-scanning"]
}
}
component {
type = "COMPONENT_SERVICE_PRINCIPAL"
instance = "secure-scanning"
service_principal_metadata = jsonencode({
gcp = {
workload_identity_federation = {
pool_provider_id = "pool_provider_id_value"
}
email = "email_value"
}
})
}
}`, accID),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "provider_type", "PROVIDER_GCP"),
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "enabled", "true"),
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "feature.0.secure_agentless_scanning.0.enabled", "true"),
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "feature.0.secure_agentless_scanning.0.components.0", "COMPONENT_SERVICE_PRINCIPAL/secure-scanning"),
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "component.0.type", "COMPONENT_SERVICE_PRINCIPAL"),
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "component.0.instance", "secure-scanning"),
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "component.0.service_principal_metadata", "{\"gcp\":{\"email\":\"email_value\",\"workload_identity_federation\":{\"pool_provider_id\":\"pool_provider_id_value\"}}}"),
),
},
{
ResourceName: "sysdig_secure_cloud_auth_account.gcp-agentless-scanning",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestGCPAgentlesScanningOnboardingWithInventory(t *testing.T) {
rText := func() string { return acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum) }
accountID := rText()
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: fmt.Sprintf(`
resource "sysdig_secure_cloud_auth_account" "gcp-agentless-scanning" {
provider_id = "gcp-agentless-test-%s"
provider_type = "PROVIDER_GCP"
enabled = true

feature {
secure_config_posture {
enabled = true
components = ["COMPONENT_SERVICE_PRINCIPAL/secure-posture"]
}

secure_agentless_scanning {
enabled = true
components = ["COMPONENT_SERVICE_PRINCIPAL/secure-scanning"]
}
}

component {
type = "COMPONENT_SERVICE_PRINCIPAL"
instance = "secure-posture"
service_principal_metadata = jsonencode({
gcp = {
key = "%s"
}
})
}

component {
type = "COMPONENT_SERVICE_PRINCIPAL"
instance = "secure-scanning"
service_principal_metadata = jsonencode({
gcp = {
workload_identity_federation = {
pool_provider_id = "pool_provider_id_value"
}
email = "email_value"
}
})
}
}`, accountID, getEncodedServiceAccountKey("sample-1", accountID)),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "provider_type", "PROVIDER_GCP"),
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "enabled", "true"),
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "feature.0.secure_agentless_scanning.0.enabled", "true"),
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "feature.0.secure_agentless_scanning.0.components.0", "COMPONENT_SERVICE_PRINCIPAL/secure-scanning"),
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "component.0.type", "COMPONENT_SERVICE_PRINCIPAL"),
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "component.0.instance", "secure-posture"),
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "component.0.service_principal_metadata", "{\"gcp\":{\"key\":\""+getEncodedServiceAccountKey("sample-1", accountID)+"\"}}"),
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "component.1.instance", "secure-scanning"),
resource.TestCheckResourceAttr("sysdig_secure_cloud_auth_account.gcp-agentless-scanning", "component.1.service_principal_metadata", "{\"gcp\":{\"email\":\"email_value\",\"workload_identity_federation\":{\"pool_provider_id\":\"pool_provider_id_value\"}}}"),
),
},
{
ResourceName: "sysdig_secure_cloud_auth_account.gcp-agentless-scanning",
ImportState: true,
ImportStateVerify: true,
},
},
})
}