Skip to content

Commit

Permalink
feat: add management of DNS server access list (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
gmichels authored Apr 5, 2023
1 parent ca752ff commit e5db827
Show file tree
Hide file tree
Showing 11 changed files with 660 additions and 1 deletion.
120 changes: 120 additions & 0 deletions adguard/dns_access_data_source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package adguard

import (
"context"

"github.com/gmichels/adguard-client-go"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
)

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

// dnsAccessDataSource is the data source implementation
type dnsAccessDataSource struct {
adg *adguard.ADG
}

// dnsAccessDataModel maps DNS Access List schema data
type dnsAccessDataModel struct {
ID types.String `tfsdk:"id"`
AllowedClients types.List `tfsdk:"allowed_clients"`
DisallowedClients types.List `tfsdk:"disallowed_clients"`
BlockedHosts types.List `tfsdk:"blocked_hosts"`
}

// NewDnsAccessDataSource is a helper function to simplify the provider implementation
func NewDnsAccessDataSource() datasource.DataSource {
return &dnsAccessDataSource{}
}

// Metadata returns the data source type name
func (d *dnsAccessDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_dns_access"
}

// Schema defines the schema for the data source
func (d *dnsAccessDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Description: "Identifier attribute",
Computed: true,
},
"allowed_clients": schema.ListAttribute{
Description: "The allowlist of clients: IP addresses, CIDRs, or ClientIDs",
ElementType: types.StringType,
Computed: true,
},
"disallowed_clients": schema.ListAttribute{
Description: "The blocklist of clients: IP addresses, CIDRs, or ClientIDs",
ElementType: types.StringType,
Computed: true,
},
"blocked_hosts": schema.ListAttribute{
Description: "Disallowed domains",
ElementType: types.StringType,
Computed: true,
},
},
}
}

// Read refreshes the Terraform state with the latest data
func (d *dnsAccessDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
// read Terraform configuration data into the model
var state dnsAccessDataModel
diags := req.Config.Get(ctx, &state)
resp.Diagnostics.Append(diags...)

// retrieve DNS Access List info
dnsAccess, err := d.adg.GetAccess()
if err != nil {
resp.Diagnostics.AddError(
"Unable to Read AdGuard Home DNS Access List",
err.Error(),
)
return
}

// map response body to model
state.AllowedClients, diags = types.ListValueFrom(ctx, types.StringType, dnsAccess.AllowedClients)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
state.DisallowedClients, diags = types.ListValueFrom(ctx, types.StringType, dnsAccess.DisallowedClients)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
state.BlockedHosts, diags = types.ListValueFrom(ctx, types.StringType, dnsAccess.BlockedHosts)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

// set ID placeholder for testing
state.ID = types.StringValue("placeholder")

// set state
diags = resp.State.Set(ctx, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
}

// Configure adds the provider configured DNS Access List to the data source
func (d *dnsAccessDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, _ *datasource.ConfigureResponse) {
if req.ProviderData == nil {
return
}

d.adg = req.ProviderData.(*adguard.ADG)
}
29 changes: 29 additions & 0 deletions adguard/dns_access_data_source_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package adguard

import (
"testing"

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

func TestAccDnsAccessDataSource(t *testing.T) {
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
// Read testing
{
Config: providerConfig + `data "adguard_dns_access" "test" { }`,
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("data.adguard_dns_access.test", "allowed_clients.#", "0"),
resource.TestCheckResourceAttr("data.adguard_dns_access.test", "disallowed_clients.#", "2"),
resource.TestCheckResourceAttr("data.adguard_dns_access.test", "disallowed_clients.1", "10.0.0.0/8"),
resource.TestCheckResourceAttr("data.adguard_dns_access.test", "blocked_hosts.#", "3"),
resource.TestCheckResourceAttr("data.adguard_dns_access.test", "blocked_hosts.1", "id.server"),

// Verify placeholder id attribute
resource.TestCheckResourceAttr("data.adguard_dns_access.test", "id", "placeholder"),
),
},
},
})
}
Loading

0 comments on commit e5db827

Please sign in to comment.