Skip to content

Commit

Permalink
feat(agent): add agent access key resource and data source (#470)
Browse files Browse the repository at this point in the history
* feat: configuring datasource for agent access keys

* feat: implementing agent access key resource with update, create, read and delete

* feat: configuring acctests, docs and changing CODEOWNERS for agentaccesskey related features

* chore: fix typo on agentaccesskey docs

* chore: fix linter

* fix: linter for unused error validation Marshaling agentAccessKey object

* feat: refactor to implement new set of APIs

* chore: change docs to new format

* chore: fix arg reference naming

* chore: fix naming convention for docs

* feat: add access_key in agent access key data source output

* chore: add platform team to list of CODEOWNERS for agentaccesskey

* chore: refactor ID and removing print
  • Loading branch information
IgorEulalio authored Apr 15, 2024
1 parent 59b1d26 commit dc02642
Show file tree
Hide file tree
Showing 12 changed files with 685 additions and 7 deletions.
7 changes: 5 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ website/node_modules
*.iml
*.test
*.iml

.tool-versions
vendor/

website/vendor
Expand All @@ -48,4 +48,7 @@ oanc
.vscode/settings.json

# goland .run
.run/
.run/

# Local test folder
local-terraform-test/
1 change: 1 addition & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
/sysdig/internal/client/v2/client.go @filiptubic @mbarbieri @draraksysdig
/sysdig/internal/client/v2/config.go @filiptubic @mbarbieri @draraksysdig
/sysdig/internal/client/v2/ibm.go @filiptubic @mbarbieri @draraksysdig
/sysdig/internal/client/v2/agentaccesskey.go @igoreulalio @filiptubic @mbarbieri @draraksysdig
/main.go @filiptubic @mbarbieri @draraksysdig
/.goreleaser.yml @filiptubic @mbarbieri @draraksysdig
/.github/ @filiptubic @mbarbieri @draraksysdig
86 changes: 86 additions & 0 deletions sysdig/data_source_agent_access_keys.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package sysdig

import (
"context"
"strconv"
"time"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

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

return &schema.Resource{
ReadContext: dataSourceSysdigAgentAccessKeyRead,

Timeouts: &schema.ResourceTimeout{
Read: schema.DefaultTimeout(timeout),
},

Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeInt,
Required: true,
},
"reservation": {
Type: schema.TypeInt,
Computed: true,
},
"limit": {
Type: schema.TypeInt,
Computed: true,
},
"team_id": {
Type: schema.TypeInt,
Computed: true,
},
"metadata": {
Type: schema.TypeMap,
Computed: true,
},
"enabled": {
Type: schema.TypeBool,
Computed: true,
},
"date_disabled": {
Type: schema.TypeString,
Computed: true,
},
"date_created": {
Type: schema.TypeString,
Computed: true,
},
"access_key": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

// Retrieves the information of a resource form the file and loads it in Terraform
func dataSourceSysdigAgentAccessKeyRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
client, err := meta.(SysdigClients).commonClientV2()
if err != nil {
return diag.FromErr(err)
}

agentKeyId := d.Get("id").(int)
agentAccessKey, err := client.GetAgentAccessKeyByID(ctx, strconv.Itoa(agentKeyId))
if err != nil {
return diag.FromErr(err)
}
d.SetId(strconv.Itoa(agentAccessKey.ID))
_ = d.Set("reservation", agentAccessKey.Reservation)
_ = d.Set("limit", agentAccessKey.Limit)
_ = d.Set("team_id", agentAccessKey.TeamID)
_ = d.Set("metadata", agentAccessKey.Metadata)
_ = d.Set("enabled", agentAccessKey.Enabled)
_ = d.Set("date_disabled", agentAccessKey.DateDisabled)
_ = d.Set("date_created", agentAccessKey.DateCreated)
_ = d.Set("access_key", agentAccessKey.AgentAccessKey)

return nil
}
66 changes: 66 additions & 0 deletions sysdig/data_source_agent_access_keys_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//go:build tf_acc_sysdig_monitor || tf_acc_sysdig_secure

package sysdig_test

import (
"fmt"
"strconv"
"testing"

"github.com/draios/terraform-provider-sysdig/sysdig"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func TestAccAgentAccessKeyDataSource(t *testing.T) {
limit := 1
reservation := 0
resource.ParallelTest(t, resource.TestCase{
PreCheck: preCheckAnyEnv(t, SysdigMonitorApiTokenEnv, SysdigSecureApiTokenEnv),
ProviderFactories: map[string]func() (*schema.Provider, error){
"sysdig": func() (*schema.Provider, error) {
return sysdig.Provider(), nil
},
},
Steps: []resource.TestStep{
{
Config: getAgentAccessKey(limit, reservation, true),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("data.sysdig_agent_access_key.data", "limit", strconv.Itoa(limit)),
resource.TestCheckResourceAttr("data.sysdig_agent_access_key.data", "reservation", strconv.Itoa(reservation)),
resource.TestCheckResourceAttr("data.sysdig_agent_access_key.data", "enabled", strconv.FormatBool(true)),
resource.TestCheckResourceAttr("data.sysdig_agent_access_key.data", "metadata.test", "yes"),
resource.TestCheckResourceAttr("data.sysdig_agent_access_key.data", "metadata.acceptance_test", "true"),
),
},
{
Config: getAgentAccessKey(limit, reservation, false),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("data.sysdig_agent_access_key.data", "limit", strconv.Itoa(limit)),
resource.TestCheckResourceAttr("data.sysdig_agent_access_key.data", "reservation", strconv.Itoa(reservation)),
resource.TestCheckResourceAttr("data.sysdig_agent_access_key.data", "enabled", strconv.FormatBool(false)),
resource.TestCheckResourceAttr("data.sysdig_agent_access_key.data", "metadata.test", "yes"),
resource.TestCheckResourceAttr("data.sysdig_agent_access_key.data", "metadata.acceptance_test", "true"),
),
},
},
})
}

func getAgentAccessKey(limit int, reservation int, enabled bool) string {
return fmt.Sprintf(`
resource "sysdig_agent_access_key" "my_agent_access_key" {
limit = %d
reservation = %d
enabled = %t
metadata = {
"test" = "yes"
"acceptance_test" = "true"
}
}
data "sysdig_agent_access_key" "data" {
id = sysdig_agent_access_key.my_agent_access_key.id
}
`, limit, reservation, enabled)
}
122 changes: 122 additions & 0 deletions sysdig/internal/client/v2/agentaccesskey.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package v2

import (
"context"
"fmt"
"net/http"
)

const (
GetAgentAccessKeyByIdPath = "%s/platform/v1/access-keys/%s"
CreateAgentAccessKeyPath = "%s/platform/v1/access-keys"
DeleteAgentAccessKeyPath = "%s/platform/v1/access-keys/%s"
PutAgentAccessKeyPath = "%s/platform/v1/access-keys/%s"
)

type AgentAccessKeyInterface interface {
Base
GetAgentAccessKeyByID(ctx context.Context, id string) (*AgentAccessKey, error)
CreateAgentAccessKey(ctx context.Context, agentAccessKey *AgentAccessKey) (*AgentAccessKey, error)
DeleteAgentAccessKey(ctx context.Context, id string) error
UpdateAgentAccessKey(ctx context.Context, agentAccessKey *AgentAccessKey, id string) (*AgentAccessKey, error)
}

func (client *Client) GetAgentAccessKeyByID(ctx context.Context, id string) (*AgentAccessKey, error) {
response, err := client.requester.Request(ctx, http.MethodGet, client.GetAgentAccessKeyByIdUrl(id), nil)
if err != nil {
return nil, err
}
defer response.Body.Close()

if response.StatusCode != http.StatusOK {
err = client.ErrorFromResponse(response)
return nil, err
}

agentAccessKey, err := Unmarshal[AgentAccessKey](response.Body)
if err != nil {
return nil, err
}

return &agentAccessKey, nil
}

func (client *Client) CreateAgentAccessKey(ctx context.Context, agentAccessKey *AgentAccessKey) (*AgentAccessKey, error) {
payload, err := Marshal(agentAccessKey)
if err != nil {
return nil, err
}
response, err := client.requester.Request(ctx, http.MethodPost, client.PostAgentAccessKeyUrl(), payload)
if err != nil {
return nil, err
}
defer response.Body.Close()

if response.StatusCode != http.StatusCreated {
err = client.ErrorFromResponse(response)
return nil, err
}

createdAgentAccessKey, err := Unmarshal[AgentAccessKey](response.Body)

if err != nil {
return nil, err
}

return &createdAgentAccessKey, nil
}

func (client *Client) UpdateAgentAccessKey(ctx context.Context, agentAccessKey *AgentAccessKey, id string) (*AgentAccessKey, error) {

payload, err := Marshal(agentAccessKey)
if err != nil {
return nil, err
}
response, err := client.requester.Request(ctx, http.MethodPut, client.PutAgentAccessKeyUrl(id), payload)
if err != nil {
return nil, err
}
defer response.Body.Close()

if response.StatusCode != http.StatusOK {
err = client.ErrorFromResponse(response)
return nil, err
}

updatedAgentAccessKey, err := Unmarshal[AgentAccessKey](response.Body)
if err != nil {
return nil, err
}

return &updatedAgentAccessKey, nil
}

func (client *Client) DeleteAgentAccessKey(ctx context.Context, id string) error {
response, err := client.requester.Request(ctx, http.MethodDelete, client.DeleteAgentAccessKeyUrl(id), nil)
if err != nil {
return err
}
defer response.Body.Close()

if response.StatusCode != http.StatusNoContent && response.StatusCode != http.StatusOK && response.StatusCode != http.StatusNotFound {
return client.ErrorFromResponse(response)
}

return nil
}

func (client *Client) GetAgentAccessKeyByIdUrl(id string) string {
return fmt.Sprintf(GetAgentAccessKeyByIdPath, client.config.url, id)
}

func (client *Client) PostAgentAccessKeyUrl() string {
return fmt.Sprintf(CreateAgentAccessKeyPath, client.config.url)
}

func (client *Client) PutAgentAccessKeyUrl(id string) string {
return fmt.Sprintf(PutAgentAccessKeyPath, client.config.url, id)
}

func (client *Client) DeleteAgentAccessKeyUrl(id string) string {
return fmt.Sprintf(DeleteAgentAccessKeyPath, client.config.url, id)
}
1 change: 1 addition & 0 deletions sysdig/internal/client/v2/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type Common interface {
TeamInterface
NotificationChannelInterface
IdentityContextInterface
AgentAccessKeyInterface
}

type MonitorCommon interface {
Expand Down
20 changes: 20 additions & 0 deletions sysdig/internal/client/v2/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -1001,6 +1001,26 @@ type SilenceRule struct {
ID int `json:"id,omitempty"`
}

type AgentAccessKey struct {
ID int `json:"id,omitempty"`
Reservation int `json:"agentReservation"`
Limit int `json:"agentLimit"`
TeamID int `json:"teamId,omitempty"`
AgentAccessKey string `json:"accessKey,omitempty"`
Metadata map[string]string `json:"metadata,omitempty"`
Enabled bool `json:"isEnabled"`
DateCreated string `json:"dateCreated,omitempty"`
DateDisabled string `json:"dateDisabled,omitempty"`
}

type AgentAccessKeyReadWrapper struct {
CustomerAccessKey []AgentAccessKey `json:"customerAccessKeys"`
}

type AgentAccessKeyWriteWrapper struct {
CustomerAccessKey AgentAccessKey `json:"customerAccessKey"`
}

type OrganizationSecure struct {
cloudauth.CloudOrganization
}
11 changes: 6 additions & 5 deletions sysdig/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ func (p *SysdigProvider) Provider() *schema.Provider {
"sysdig_group_mapping_config": resourceSysdigGroupMappingConfig(),
"sysdig_custom_role": resourceSysdigCustomRole(),
"sysdig_team_service_account": resourceSysdigTeamServiceAccount(),
"sysdig_agent_access_key": resourceSysdigAgentAccessKey(),

"sysdig_secure_aws_ml_policy": resourceSysdigSecureAWSMLPolicy(),
"sysdig_secure_custom_policy": resourceSysdigSecureCustomPolicy(),
Expand Down Expand Up @@ -219,11 +220,11 @@ func (p *SysdigProvider) Provider() *schema.Provider {
"sysdig_secure_posture_policies": dataSourceSysdigSecurePosturePolicies(),
"sysdig_secure_custom_role_permissions": dataSourceSysdigSecureCustomRolePermissions(),

"sysdig_current_user": dataSourceSysdigCurrentUser(),
"sysdig_user": dataSourceSysdigUser(),
"sysdig_secure_connection": dataSourceSysdigSecureConnection(),
"sysdig_custom_role": dataSourceSysdigCustomRole(),

"sysdig_current_user": dataSourceSysdigCurrentUser(),
"sysdig_user": dataSourceSysdigUser(),
"sysdig_secure_connection": dataSourceSysdigSecureConnection(),
"sysdig_custom_role": dataSourceSysdigCustomRole(),
"sysdig_agent_access_key": dataSourceSysdigAgentAccessKey(),
"sysdig_fargate_workload_agent": dataSourceSysdigFargateWorkloadAgent(),
"sysdig_monitor_notification_channel_pagerduty": dataSourceSysdigMonitorNotificationChannelPagerduty(),
"sysdig_monitor_notification_channel_email": dataSourceSysdigMonitorNotificationChannelEmail(),
Expand Down
Loading

0 comments on commit dc02642

Please sign in to comment.