Skip to content

Commit

Permalink
Add appliance firewalled service resource and data source
Browse files Browse the repository at this point in the history
  • Loading branch information
danischm committed Oct 1, 2024
1 parent 89aa167 commit 967a9c9
Show file tree
Hide file tree
Showing 15 changed files with 870 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.1.2 (unreleased)

- Add `meraki_appliance_firewalled_service` resource and data source

## 0.1.1

- Add `meraki_network_floor_plans` data source
Expand Down
34 changes: 34 additions & 0 deletions docs/data-sources/appliance_firewalled_service.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "meraki_appliance_firewalled_service Data Source - terraform-provider-meraki"
subcategory: "Appliances"
description: |-
This data source can read the Appliance Firewalled Service configuration.
---

# meraki_appliance_firewalled_service (Data Source)

This data source can read the `Appliance Firewalled Service` configuration.

## Example Usage

```terraform
data "meraki_appliance_firewalled_service" "example" {
network_id = "L_123456"
service = "ICMP"
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `network_id` (String) Network ID
- `service` (String) Service

### Read-Only

- `access` (String) A string indicating the rule for which IPs are allowed to use the specified service. Acceptable values are 'blocked' (no remote IPs can access the service), 'restricted' (only allowed IPs can access the service), and 'unrestriced' (any remote IP can access the service). This field is required
- `allowed_ips` (List of String) An array of allowed IPs that can access the service. This field is required if 'access' is set to 'restricted'. Otherwise this field is ignored
- `id` (String) The id of the object
4 changes: 4 additions & 0 deletions docs/guides/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ description: |-

# Changelog

## 0.1.2 (unreleased)

- Add `meraki_appliance_firewalled_service` resource and data source

## 0.1.1

- Add `meraki_network_floor_plans` data source
Expand Down
49 changes: 49 additions & 0 deletions docs/resources/appliance_firewalled_service.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "meraki_appliance_firewalled_service Resource - terraform-provider-meraki"
subcategory: "Appliances"
description: |-
This resource can manage the Appliance Firewalled Service configuration.
---

# meraki_appliance_firewalled_service (Resource)

This resource can manage the `Appliance Firewalled Service` configuration.

## Example Usage

```terraform
resource "meraki_appliance_firewalled_service" "example" {
network_id = "L_123456"
service = "ICMP"
access = "restricted"
allowed_ips = ["123.123.123.1"]
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `access` (String) A string indicating the rule for which IPs are allowed to use the specified service. Acceptable values are 'blocked' (no remote IPs can access the service), 'restricted' (only allowed IPs can access the service), and 'unrestriced' (any remote IP can access the service). This field is required
- Choices: `blocked`, `restricted`, `unrestricted`
- `network_id` (String) Network ID
- `service` (String) Service
- Choices: `ICMP`, `SNMP`, `web`

### Optional

- `allowed_ips` (List of String) An array of allowed IPs that can access the service. This field is required if 'access' is set to 'restricted'. Otherwise this field is ignored

### Read-Only

- `id` (String) The id of the object

## Import

Import is supported using the following syntax:

```shell
terraform import meraki_appliance_firewalled_service.example "<network_id>,<service>"
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
data "meraki_appliance_firewalled_service" "example" {
network_id = "L_123456"
service = "ICMP"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
terraform import meraki_appliance_firewalled_service.example "<network_id>,<service>"
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
resource "meraki_appliance_firewalled_service" "example" {
network_id = "L_123456"
service = "ICMP"
access = "restricted"
allowed_ips = ["123.123.123.1"]
}
42 changes: 42 additions & 0 deletions gen/definitions/appliance_firewalled_service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Appliance Firewalled Service
spec_endpoint: /networks/{networkId}/appliance/firewall/firewalledServices/{service}
rest_endpoint: /networks/%v/appliance/firewall/firewalledServices/%v
put_create: true
no_delete: true
doc_category: Appliances
test_variables: [test_org, test_network]
attributes:
- tf_name: network_id
type: String
reference: true
description: Network ID
example: L_123456
test_value: meraki_network.test.id
- tf_name: service
type: String
id: true
reference: true
description: Service
example: ICMP
enum_values: [ICMP, SNMP, web]
- model_name: access
type: String
mandatory: true
description: A string indicating the rule for which IPs are allowed to use the specified service. Acceptable values are 'blocked' (no remote IPs can access the service), 'restricted' (only allowed IPs can access the service), and 'unrestriced' (any remote IP can access the service). This field is required
example: restricted
enum_values: [blocked, restricted, unrestricted]
minimum_test_value: '"unrestricted"'
- model_name: allowedIps
type: List
element_type: String
description: An array of allowed IPs that can access the service. This field is required if 'access' is set to 'restricted'. Otherwise this field is ignored
example: 123.123.123.1
test_prerequisites: |
data "meraki_organization" "test" {
name = var.test_org
}
resource "meraki_network" "test" {
organization_id = data.meraki_organization.test.id
name = var.test_network
product_types = ["switch", "wireless", "appliance"]
}
129 changes: 129 additions & 0 deletions internal/provider/data_source_meraki_appliance_firewalled_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// Copyright © 2024 Cisco Systems, Inc. and its affiliates.
// All rights reserved.
//
// Licensed under the Mozilla Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://mozilla.org/MPL/2.0/
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: MPL-2.0

package provider

// Section below is generated&owned by "gen/generator.go". //template:begin imports
import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/netascode/go-meraki"
)

// End of section. //template:end imports

// Section below is generated&owned by "gen/generator.go". //template:begin model

// Ensure the implementation satisfies the expected interfaces.
var (
_ datasource.DataSource = &ApplianceFirewalledServiceDataSource{}
_ datasource.DataSourceWithConfigure = &ApplianceFirewalledServiceDataSource{}
)

func NewApplianceFirewalledServiceDataSource() datasource.DataSource {
return &ApplianceFirewalledServiceDataSource{}
}

type ApplianceFirewalledServiceDataSource struct {
client *meraki.Client
}

func (d *ApplianceFirewalledServiceDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_appliance_firewalled_service"
}

func (d *ApplianceFirewalledServiceDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
// This description is used by the documentation generator and the language server.
MarkdownDescription: "This data source can read the `Appliance Firewalled Service` configuration.",

Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
MarkdownDescription: "The id of the object",
Computed: true,
},
"network_id": schema.StringAttribute{
MarkdownDescription: "Network ID",
Required: true,
},
"service": schema.StringAttribute{
MarkdownDescription: "Service",
Required: true,
},
"access": schema.StringAttribute{
MarkdownDescription: "A string indicating the rule for which IPs are allowed to use the specified service. Acceptable values are 'blocked' (no remote IPs can access the service), 'restricted' (only allowed IPs can access the service), and 'unrestriced' (any remote IP can access the service). This field is required",
Computed: true,
},
"allowed_ips": schema.ListAttribute{
MarkdownDescription: "An array of allowed IPs that can access the service. This field is required if 'access' is set to 'restricted'. Otherwise this field is ignored",
ElementType: types.StringType,
Computed: true,
},
},
}
}

func (d *ApplianceFirewalledServiceDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, _ *datasource.ConfigureResponse) {
if req.ProviderData == nil {
return
}

d.client = req.ProviderData.(*MerakiProviderData).Client
}

// End of section. //template:end model

// Section below is generated&owned by "gen/generator.go". //template:begin read

func (d *ApplianceFirewalledServiceDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var config ApplianceFirewalledService

// Read config
diags := req.Config.Get(ctx, &config)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Read", config.Id.String()))

var res meraki.Res
var err error

if !res.Exists() {
res, err = d.client.Get(config.getPath())
if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to retrieve object, got error: %s", err))
return
}
}

config.fromBody(ctx, res)
config.Id = config.Service

tflog.Debug(ctx, fmt.Sprintf("%s: Read finished successfully", config.Id.ValueString()))

diags = resp.State.Set(ctx, &config)
resp.Diagnostics.Append(diags...)
}

// End of section. //template:end read
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Copyright © 2024 Cisco Systems, Inc. and its affiliates.
// All rights reserved.
//
// Licensed under the Mozilla Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://mozilla.org/MPL/2.0/
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: MPL-2.0

package provider

// Section below is generated&owned by "gen/generator.go". //template:begin imports
import (
"os"
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
)

// End of section. //template:end imports

// Section below is generated&owned by "gen/generator.go". //template:begin testAccDataSource

func TestAccDataSourceMerakiApplianceFirewalledService(t *testing.T) {
if os.Getenv("TF_VAR_test_org") == "" || os.Getenv("TF_VAR_test_network") == "" {
t.Skip("skipping test, set environment variable TF_VAR_test_org and TF_VAR_test_network")
}
var checks []resource.TestCheckFunc
checks = append(checks, resource.TestCheckResourceAttr("data.meraki_appliance_firewalled_service.test", "service", "ICMP"))
checks = append(checks, resource.TestCheckResourceAttr("data.meraki_appliance_firewalled_service.test", "access", "restricted"))
checks = append(checks, resource.TestCheckResourceAttr("data.meraki_appliance_firewalled_service.test", "allowed_ips.0", "123.123.123.1"))
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccDataSourceMerakiApplianceFirewalledServicePrerequisitesConfig + testAccDataSourceMerakiApplianceFirewalledServiceConfig(),
Check: resource.ComposeTestCheckFunc(checks...),
},
},
})
}

// End of section. //template:end testAccDataSource

// Section below is generated&owned by "gen/generator.go". //template:begin testPrerequisites

const testAccDataSourceMerakiApplianceFirewalledServicePrerequisitesConfig = `
variable "test_org" {}
variable "test_network" {}
data "meraki_organization" "test" {
name = var.test_org
}
resource "meraki_network" "test" {
organization_id = data.meraki_organization.test.id
name = var.test_network
product_types = ["switch", "wireless", "appliance"]
}
`

// End of section. //template:end testPrerequisites

// Section below is generated&owned by "gen/generator.go". //template:begin testAccDataSourceConfig

func testAccDataSourceMerakiApplianceFirewalledServiceConfig() string {
config := `resource "meraki_appliance_firewalled_service" "test" {` + "\n"
config += ` network_id = meraki_network.test.id` + "\n"
config += ` service = "ICMP"` + "\n"
config += ` access = "restricted"` + "\n"
config += ` allowed_ips = ["123.123.123.1"]` + "\n"
config += `}` + "\n"

config += `
data "meraki_appliance_firewalled_service" "test" {
network_id = meraki_network.test.id
service = "ICMP"
depends_on = [meraki_appliance_firewalled_service.test]
}
`
return config
}

// End of section. //template:end testAccDataSourceConfig
Loading

0 comments on commit 967a9c9

Please sign in to comment.