Skip to content

Commit

Permalink
Add support for bulk url resource and data source (#182)
Browse files Browse the repository at this point in the history
  • Loading branch information
mmaciejc authored Nov 18, 2024
1 parent 02e9b87 commit 648ed76
Show file tree
Hide file tree
Showing 12 changed files with 1,256 additions and 0 deletions.
44 changes: 44 additions & 0 deletions docs/data-sources/urls.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "fmc_urls Data Source - terraform-provider-fmc"
subcategory: "Objects"
description: |-
This data source can read the URLs.
---

# fmc_urls (Data Source)

This data source can read the URLs.

## Example Usage

```terraform
data "fmc_urls" "example" {
items = {
"url_1" = {
}
}
}
```

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

### Optional

- `domain` (String) The name of the FMC domain
- `items` (Attributes Map) Map of security zones. The key of the map is the name of the individual URL object. Renaming URL object in bulk is not yet implemented. (see [below for nested schema](#nestedatt--items))

### Read-Only

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

<a id="nestedatt--items"></a>
### Nested Schema for `items`

Read-Only:

- `description` (String) Optional user-created description.
- `id` (String) UUID of the managed URL object.
- `overridable` (Boolean) Indicates whether object values can be overridden.
- `url` (String) URL value.
63 changes: 63 additions & 0 deletions docs/resources/urls.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "fmc_urls Resource - terraform-provider-fmc"
subcategory: "Objects"
description: |-
This plural resource manages a bulk of URL objects. The FMC API supports quick bulk creation of this resource. Deletion of this resource is done one-by-one or in bulk, depending of FMC version. Modification is always done one-by-one. Updating/deleting fmc_urls can thus take much more time than creating it
---

# fmc_urls (Resource)

This plural resource manages a bulk of URL objects. The FMC API supports quick bulk creation of this resource. Deletion of this resource is done one-by-one or in bulk, depending of FMC version. Modification is always done one-by-one. Updating/deleting `fmc_urls` can thus take much more time than creating it

## Example Usage

```terraform
resource "fmc_urls" "example" {
items = {
url_1 = {
url = "https://www.example.com/app"
description = "My URL"
}
}
}
```

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

### Required

- `items` (Attributes Map) Map of security zones. The key of the map is the name of the individual URL object. Renaming URL object in bulk is not yet implemented. (see [below for nested schema](#nestedatt--items))

### Optional

- `domain` (String) The name of the FMC domain

### Read-Only

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

<a id="nestedatt--items"></a>
### Nested Schema for `items`

Required:

- `url` (String) URL value.

Optional:

- `description` (String) Optional user-created description.
- `overridable` (Boolean) Indicates whether object values can be overridden.

Read-Only:

- `id` (String) UUID of the managed URL object.

## Import

Import is supported using the following syntax:

```shell
terraform import fmc_urls.example "<domain>,[<urls_name>]"
```
6 changes: 6 additions & 0 deletions examples/data-sources/fmc_urls/data-source.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
data "fmc_urls" "example" {
items = {
"url_1" = {
}
}
}
1 change: 1 addition & 0 deletions examples/resources/fmc_urls/import.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
terraform import fmc_urls.example "<domain>,[<urls_name>]"
8 changes: 8 additions & 0 deletions examples/resources/fmc_urls/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
resource "fmc_urls" "example" {
items = {
url_1 = {
url = "https://www.example.com/app"
description = "My URL"
}
}
}
40 changes: 40 additions & 0 deletions gen/definitions/urls.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
name: URLs
rest_endpoint: /api/fmc_config/v1/domain/{DOMAIN_UUID}/object/urls
is_bulk: true
data_source_name_query: true
import_name_query: yes
res_description: >-
This plural resource manages a bulk of URL objects.
The FMC API supports quick bulk creation of this resource. Deletion of this resource is done one-by-one or in bulk, depending of FMC version. Modification is always done one-by-one.
Updating/deleting `fmc_urls` can thus take much more time than creating it
doc_category: Objects
attributes:
- model_name: items
type: Map
description: >-
Map of security zones. The key of the map is the name of the individual URL object. Renaming URL object in bulk
is not yet implemented.
map_key_example: url_1
mandatory: true
attributes:
- model_name: id
type: String
resource_id: true
description: UUID of the managed URL object.
exclude_example: true
exclude_test: true
- model_name: url
type: String
description: URL value.
mandatory: true
example: "https://www.example.com/app"
- model_name: description
type: String
description: Optional user-created description.
example: "My URL"
- model_name: overridable
type: Bool
description: Indicates whether object values can be overridden.
exclude_example: true
test_value: "true"
142 changes: 142 additions & 0 deletions internal/provider/data_source_fmc_urls.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
// Copyright © 2023 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-log/tflog"
"github.com/netascode/go-fmc"
)

// 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 = &URLsDataSource{}
_ datasource.DataSourceWithConfigure = &URLsDataSource{}
)

func NewURLsDataSource() datasource.DataSource {
return &URLsDataSource{}
}

type URLsDataSource struct {
client *fmc.Client
}

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

func (d *URLsDataSource) 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 URLs.",

Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
MarkdownDescription: "The id of the object",
Computed: true,
},
"domain": schema.StringAttribute{
MarkdownDescription: "The name of the FMC domain",
Optional: true,
},
"items": schema.MapNestedAttribute{
MarkdownDescription: "Map of security zones. The key of the map is the name of the individual URL object. Renaming URL object in bulk is not yet implemented.",
Optional: true,
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
MarkdownDescription: "UUID of the managed URL object.",
Computed: true,
},
"url": schema.StringAttribute{
MarkdownDescription: "URL value.",
Computed: true,
},
"description": schema.StringAttribute{
MarkdownDescription: "Optional user-created description.",
Computed: true,
},
"overridable": schema.BoolAttribute{
MarkdownDescription: "Indicates whether object values can be overridden.",
Computed: true,
},
},
},
},
},
}
}

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

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

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

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

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

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

// Set request domain if provided
reqMods := [](func(*fmc.Req)){}
if !config.Domain.IsNull() && config.Domain.ValueString() != "" {
reqMods = append(reqMods, fmc.DomainName(config.Domain.ValueString()))
}

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

// Get all objects from FMC
urlPath := config.getPath() + "?expanded=true"
res, err := d.client.Get(urlPath, reqMods...)
if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to retrieve object, got error: %s", err))
return
}

config.fromBody(ctx, res)

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
76 changes: 76 additions & 0 deletions internal/provider/data_source_fmc_urls_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Copyright © 2023 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 (
"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 TestAccDataSourceFmcURLs(t *testing.T) {
var checks []resource.TestCheckFunc
checks = append(checks, resource.TestCheckResourceAttrSet("data.fmc_urls.test", "items.url_1.id"))
checks = append(checks, resource.TestCheckResourceAttr("data.fmc_urls.test", "items.url_1.url", "https://www.example.com/app"))
checks = append(checks, resource.TestCheckResourceAttr("data.fmc_urls.test", "items.url_1.description", "My URL"))
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccDataSourceFmcURLsConfig(),
Check: resource.ComposeTestCheckFunc(checks...),
},
},
})
}

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

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

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

func testAccDataSourceFmcURLsConfig() string {
config := `resource "fmc_urls" "test" {` + "\n"
config += ` items = { "url_1" = {` + "\n"
config += ` url = "https://www.example.com/app"` + "\n"
config += ` description = "My URL"` + "\n"
config += ` overridable = true` + "\n"
config += ` }}` + "\n"
config += `}` + "\n"

config += `
data "fmc_urls" "test" {
depends_on = [fmc_urls.test]
items = {
"url_1" = {
}
}
}
`
return config
}

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

0 comments on commit 648ed76

Please sign in to comment.