Skip to content

Commit

Permalink
feat(ip filter) Add ip filter resource for both monitor and secure (#534
Browse files Browse the repository at this point in the history
)

* feat(allowed ip range) Add allowed ip range resource for both monitor and secure SP-3101

* add build tag to acc test

* remove unused `allowedIpRangeWrapper`

* rename resource: 'allowed_ip_range' > 'ip_filter'

* remove check for status 200 when deleting ip filter

* minor refactor - change 'Ip' > 'IP' in method names

* add ip_filters_settings resource used for enabling/disabling IP filters

* update `sysdig_ip_filters_settings` documentation

* rename helper methods in tests

* add Attributes Reference to docs

* rename `ip_filters_settings` resource to `ip_filtering_settings`
  • Loading branch information
vojindj authored Sep 9, 2024
1 parent 10d96d7 commit 779e9c0
Show file tree
Hide file tree
Showing 12 changed files with 637 additions and 7 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ $ cd terraform-provider-sysdig
$ make build
```

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

### Creating new resource / data sources

Expand Down
65 changes: 65 additions & 0 deletions sysdig/internal/client/v2/ip_filtering_settings.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package v2

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

const (
IPFiltersSettingsPath = "%s/platform/v1/ip-filters-settings"
)

type IPFilteringSettingsInterface interface {
Base
GetIPFilteringSettings(ctx context.Context) (*IPFiltersSettings, error)
UpdateIPFilteringSettings(ctx context.Context, ipFiltersSettings *IPFiltersSettings) (*IPFiltersSettings, error)
}

func (client *Client) GetIPFilteringSettings(ctx context.Context) (*IPFiltersSettings, error) {
response, err := client.requester.Request(ctx, http.MethodGet, client.GetIPFiltersSettingsURL(), nil)
if err != nil {
return nil, err
}
defer response.Body.Close()

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

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

return &ipFiltersSettings, nil
}

func (client *Client) UpdateIPFilteringSettings(ctx context.Context, ipFiltersSettings *IPFiltersSettings) (*IPFiltersSettings, error) {
payload, err := Marshal(ipFiltersSettings)
if err != nil {
return nil, err
}

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

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

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

return &updated, nil
}

func (client *Client) GetIPFiltersSettingsURL() string {
return fmt.Sprintf(IPFiltersSettingsPath, client.config.url)
}
114 changes: 114 additions & 0 deletions sysdig/internal/client/v2/ip_filters.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package v2

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

var IPFilterNotFound = errors.New("IP filter not found")

const (
IPFiltersPath = "%s/platform/v1/ip-filters"
IPFilterPath = "%s/platform/v1/ip-filters/%d"
)

type IPFiltersInterface interface {
Base
GetIPFilterById(ctx context.Context, id int) (*IPFilter, error)
CreateIPFilter(ctx context.Context, ipFilter *IPFilter) (*IPFilter, error)
UpdateIPFilter(ctx context.Context, ipFilter *IPFilter, id int) (*IPFilter, error)
DeleteIPFilter(ctx context.Context, id int) error
}

func (client *Client) GetIPFilterById(ctx context.Context, id int) (*IPFilter, error) {
response, err := client.requester.Request(ctx, http.MethodGet, client.GetIPFilterURL(id), nil)
if err != nil {
return nil, err
}
defer response.Body.Close()

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

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

return &ipFilter, nil
}

func (client *Client) CreateIPFilter(ctx context.Context, ipFilter *IPFilter) (*IPFilter, error) {
payload, err := Marshal(ipFilter)
if err != nil {
return nil, err
}

response, err := client.requester.Request(ctx, http.MethodPost, client.GetIPFiltersURL(), payload)
if err != nil {
return nil, err
}
defer response.Body.Close()

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

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

return &created, nil

}

func (client *Client) UpdateIPFilter(ctx context.Context, ipFilter *IPFilter, id int) (*IPFilter, error) {
payload, err := Marshal(ipFilter)
if err != nil {
return nil, err
}

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

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

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

return &updated, nil
}

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

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

return nil
}

func (client *Client) GetIPFilterURL(id int) string {
return fmt.Sprintf(IPFilterPath, client.config.url, id)
}

func (client *Client) GetIPFiltersURL() string {
return fmt.Sprintf(IPFiltersPath, client.config.url)
}
12 changes: 12 additions & 0 deletions sysdig/internal/client/v2/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,18 @@ type GroupMappingConfig struct {
DifferentTeamSameRoleStrategy string `json:"differentRolesSameTeamStrategy"`
}

type IPFilter struct {
ID int `json:"id,omitempty"`
IPRange string `json:"ipRange"`
Note string `json:"note,omitempty"`
Enabled bool `json:"isEnabled"`
LastUpdated string `json:"lastUpdated,omitempty"`
}

type IPFiltersSettings struct {
IPFilteringEnabled bool `json:"isFilteringEnabled"`
}

type alertWrapper struct {
Alert Alert `json:"alert"`
}
Expand Down
2 changes: 2 additions & 0 deletions sysdig/internal/client/v2/sysdig.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ type SysdigCommon interface {
CustomRoleInterface
CustomRolePermissionInterface
TeamServiceAccountInterface
IPFiltersInterface
IPFilteringSettingsInterface
}

type SysdigMonitor interface {
Expand Down
14 changes: 8 additions & 6 deletions sysdig/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,14 @@ func (p *SysdigProvider) Provider() *schema.Provider {
},
},
ResourcesMap: map[string]*schema.Resource{
"sysdig_user": resourceSysdigUser(),
"sysdig_group_mapping": resourceSysdigGroupMapping(),
"sysdig_group_mapping_config": resourceSysdigGroupMappingConfig(),
"sysdig_custom_role": resourceSysdigCustomRole(),
"sysdig_team_service_account": resourceSysdigTeamServiceAccount(),
"sysdig_agent_access_key": resourceSysdigAgentAccessKey(),
"sysdig_user": resourceSysdigUser(),
"sysdig_group_mapping": resourceSysdigGroupMapping(),
"sysdig_group_mapping_config": resourceSysdigGroupMappingConfig(),
"sysdig_custom_role": resourceSysdigCustomRole(),
"sysdig_team_service_account": resourceSysdigTeamServiceAccount(),
"sysdig_agent_access_key": resourceSysdigAgentAccessKey(),
"sysdig_ip_filter": resourceSysdigIPFilter(),
"sysdig_ip_filtering_settings": resourceSysdigIPFilteringSettings(),

"sysdig_secure_aws_ml_policy": resourceSysdigSecureAWSMLPolicy(),
"sysdig_secure_custom_policy": resourceSysdigSecureCustomPolicy(),
Expand Down
155 changes: 155 additions & 0 deletions sysdig/resource_sysdig_ip_filter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package sysdig

import (
"context"
v2 "github.com/draios/terraform-provider-sysdig/sysdig/internal/client/v2"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"strconv"
)

func resourceSysdigIPFilter() *schema.Resource {
return &schema.Resource{
ReadContext: resourceSysdigIPFilterRead,
CreateContext: resourceSysdigIPFilterCreate,
UpdateContext: resourceSysdigIPFilterUpdate,
DeleteContext: resourceSysdigIPFilterDelete,
Schema: map[string]*schema.Schema{
"ip_range": {
Type: schema.TypeString,
Required: true,
},
"note": {
Type: schema.TypeString,
Optional: true,
},
"enabled": {
Type: schema.TypeBool,
Required: true,
},
},
}
}

func resourceSysdigIPFilterRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
client, err := m.(SysdigClients).sysdigCommonClientV2()
if err != nil {
return diag.FromErr(err)
}

id, err := strconv.Atoi(d.Id())
if err != nil {
return diag.FromErr(err)
}

ipFilter, err := client.GetIPFilterById(ctx, id)
if err != nil {
if err == v2.IPFilterNotFound {
d.SetId("")
return nil
}
return diag.FromErr(err)
}

err = ipFilterToResourceData(ipFilter, d)
if err != nil {
return diag.FromErr(err)
}

return nil
}

func resourceSysdigIPFilterCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
client, err := m.(SysdigClients).sysdigCommonClientV2()
if err != nil {
return diag.FromErr(err)
}

ipFilter, err := ipFilterFromResourceData(d)
if err != nil {
return diag.FromErr(err)
}

createdIPFilter, err := client.CreateIPFilter(ctx, ipFilter)
if err != nil {
return diag.FromErr(err)
}

d.SetId(strconv.Itoa(createdIPFilter.ID))

resourceSysdigIPFilterRead(ctx, d, m)

return nil
}

func resourceSysdigIPFilterUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
client, err := m.(SysdigClients).sysdigCommonClientV2()
if err != nil {
return diag.FromErr(err)
}

ipFilter, err := ipFilterFromResourceData(d)
if err != nil {
return diag.FromErr(err)
}

id, err := strconv.Atoi(d.Id())
if err != nil {
return diag.FromErr(err)

}

ipFilter.ID = id
_, err = client.UpdateIPFilter(ctx, ipFilter, id)
if err != nil {
return diag.FromErr(err)
}

resourceSysdigIPFilterRead(ctx, d, m)

return nil
}

func resourceSysdigIPFilterDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
client, err := m.(SysdigClients).sysdigCommonClientV2()
if err != nil {
return diag.FromErr(err)
}

id, err := strconv.Atoi(d.Id())
if err != nil {
return diag.FromErr(err)
}

err = client.DeleteIPFilter(ctx, id)
if err != nil {
return diag.FromErr(err)
}

return nil
}

func ipFilterToResourceData(ipFilter *v2.IPFilter, d *schema.ResourceData) error {
err := d.Set("ip_range", ipFilter.IPRange)
if err != nil {
return err
}
err = d.Set("note", ipFilter.Note)
if err != nil {
return err
}
err = d.Set("enabled", ipFilter.Enabled)
if err != nil {
return err
}

return nil
}

func ipFilterFromResourceData(d *schema.ResourceData) (*v2.IPFilter, error) {
return &v2.IPFilter{
IPRange: d.Get("ip_range").(string),
Note: d.Get("note").(string),
Enabled: d.Get("enabled").(bool),
}, nil
}
Loading

0 comments on commit 779e9c0

Please sign in to comment.