Skip to content

Commit

Permalink
Add additional properties to tenant_resource
Browse files Browse the repository at this point in the history
  • Loading branch information
kurtmc committed May 6, 2024
1 parent 10abe3f commit 3e32b90
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 23 deletions.
2 changes: 1 addition & 1 deletion client/chirpstack.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (

type Chirpstack interface {
// tenant
CreateTenant(ctx context.Context, name, description string) (string, error)
CreateTenant(ctx context.Context, tenant *api.Tenant) (string, error)
GetTenant(ctx context.Context, id string) (*api.Tenant, error)
UpdateTenant(ctx context.Context, tenant *api.Tenant) error
DeleteTenant(ctx context.Context, id string) error
Expand Down
14 changes: 5 additions & 9 deletions client/tenant.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,12 @@ func (c *chirpstack) GetTenant(ctx context.Context, id string) (*api.Tenant, err
return resp.Tenant, nil
}

func (c *chirpstack) CreateTenant(ctx context.Context, name, description string) (string, error) {
createTenantsRequest := api.CreateTenantRequest{
Tenant: &api.Tenant{
Name: name,
Description: description,
},
}
listTenantsResponse, err := c.tenantServiceClient.Create(ctx, &createTenantsRequest)
func (c *chirpstack) CreateTenant(ctx context.Context, tenant *api.Tenant) (string, error) {
listTenantsResponse, err := c.tenantServiceClient.Create(ctx, &api.CreateTenantRequest{
Tenant: tenant,
})
if err != nil {
return "", fmt.Errorf("failed to create tenant %s; err: %s;", name, err)
return "", fmt.Errorf("failed to create tenant %+v; err: %s;", tenant, err)
}
return listTenantsResponse.Id, nil
}
Expand Down
9 changes: 9 additions & 0 deletions docs/resources/tenant.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,16 @@ resource "chirpstack_tenant" "tenant" {

### Optional

- `can_have_gateways` (Boolean) Can the tenant create and "own" Gateways?
- `description` (String) Tenant description
- `max_device_count` (Number) Max. device count for tenant. When set to 0, the tenant can have unlimited devices.
- `max_gateway_count` (Number) Max. gateway count for tenant. When set to 0, the tenant can have unlimited gateways.
- `private_gateways_down` (Boolean) Private gateways (downlink).
If enabled, then other tenants will not be able to schedule downlink
messages through the gateways of this tenant. For example, in case you
do want to share uplinks with other tenants (private_gateways_up=false),
but you want to prevent other tenants from using gateway airtime.
- `private_gateways_up` (Boolean) Private gateways (uplink). If enabled, then uplink messages will not be shared with other tenants.

### Read-Only

Expand Down
93 changes: 80 additions & 13 deletions internal/provider/tenant_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,14 @@ type TenantResource struct {

// TenantResourceModel describes the resource data model.
type TenantResourceModel struct {
Name types.String `tfsdk:"name"`
Description types.String `tfsdk:"description"`
Id types.String `tfsdk:"id"`
Name types.String `tfsdk:"name"`
Description types.String `tfsdk:"description"`
Id types.String `tfsdk:"id"`
CanHaveGateways types.Bool `tfsdk:"can_have_gateways"`
MaxGatewayCount types.Int64 `tfsdk:"max_gateway_count"`
MaxDeviceCount types.Int64 `tfsdk:"max_device_count"`
PrivateGatewaysUp types.Bool `tfsdk:"private_gateways_up"`
PrivateGatewaysDown types.Bool `tfsdk:"private_gateways_down"`
}

func (r *TenantResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
Expand Down Expand Up @@ -62,6 +67,35 @@ func (r *TenantResource) Schema(ctx context.Context, req resource.SchemaRequest,
MarkdownDescription: "Tenant description",
Optional: true,
},
"can_have_gateways": schema.BoolAttribute{
MarkdownDescription: `Can the tenant create and "own" Gateways?`,
Optional: true,
Computed: true,
},
"max_gateway_count": schema.Int64Attribute{
MarkdownDescription: "Max. gateway count for tenant. When set to 0, the tenant can have unlimited gateways.",
Optional: true,
Computed: true,
},
"max_device_count": schema.Int64Attribute{
MarkdownDescription: "Max. device count for tenant. When set to 0, the tenant can have unlimited devices.",
Optional: true,
Computed: true,
},
"private_gateways_up": schema.BoolAttribute{
MarkdownDescription: "Private gateways (uplink). If enabled, then uplink messages will not be shared with other tenants.",
Optional: true,
Computed: true,
},
"private_gateways_down": schema.BoolAttribute{
MarkdownDescription: `Private gateways (downlink).
If enabled, then other tenants will not be able to schedule downlink
messages through the gateways of this tenant. For example, in case you
do want to share uplinks with other tenants (private_gateways_up=false),
but you want to prevent other tenants from using gateway airtime.`,
Optional: true,
Computed: true,
},
},
}
}
Expand All @@ -85,6 +119,42 @@ func (r *TenantResource) Configure(ctx context.Context, req resource.ConfigureRe

r.chirpstack = chirpstack
}
func tenantFromData(data *TenantResourceModel) *api.Tenant {
tenant := api.Tenant{
Id: data.Id.ValueString(),
Name: data.Name.ValueString(),
}
if !data.Description.IsNull() {
tenant.Description = data.Description.ValueString()
}
if !data.CanHaveGateways.IsNull() {
tenant.CanHaveGateways = data.CanHaveGateways.ValueBool()
}
if !data.MaxGatewayCount.IsNull() {
tenant.MaxGatewayCount = uint32(data.MaxGatewayCount.ValueInt64())
}
if !data.MaxDeviceCount.IsNull() {
tenant.MaxDeviceCount = uint32(data.MaxDeviceCount.ValueInt64())
}
if !data.PrivateGatewaysUp.IsNull() {
tenant.PrivateGatewaysUp = data.PrivateGatewaysUp.ValueBool()
}
if !data.PrivateGatewaysDown.IsNull() {
tenant.PrivateGatewaysDown = data.PrivateGatewaysDown.ValueBool()
}
return &tenant
}
func tenantToData(tenant *api.Tenant, data *TenantResourceModel) {
data.Name = types.StringValue(tenant.Name)
if tenant.Description != "" {
data.Description = types.StringValue(tenant.Description)
}
data.CanHaveGateways = types.BoolValue(tenant.CanHaveGateways)
data.MaxGatewayCount = types.Int64Value(int64(tenant.MaxGatewayCount))
data.MaxDeviceCount = types.Int64Value(int64(tenant.MaxDeviceCount))
data.PrivateGatewaysUp = types.BoolValue(tenant.PrivateGatewaysUp)
data.PrivateGatewaysDown = types.BoolValue(tenant.PrivateGatewaysDown)
}

func (r *TenantResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
var data TenantResourceModel
Expand All @@ -103,7 +173,8 @@ func (r *TenantResource) Create(ctx context.Context, req resource.CreateRequest,
// resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to create tenant, got error: %s", err))
// return
// }
id, err := r.chirpstack.CreateTenant(ctx, data.Name.ValueString(), data.Description.ValueString())
tenant := tenantFromData(&data)
id, err := r.chirpstack.CreateTenant(ctx, tenant)
if err != nil {
resp.Diagnostics.AddError("Chirpstack Error", fmt.Sprintf("Unable to create tenant, got error: %s", err))
return
Expand All @@ -112,6 +183,7 @@ func (r *TenantResource) Create(ctx context.Context, req resource.CreateRequest,
// For the purposes of this tenant code, hardcoding a response value to
// save into the Terraform state.
data.Id = types.StringValue(id)
tenantToData(tenant, &data)

// Write logs using the tflog package
// Documentation: https://terraform.io/plugin/log
Expand Down Expand Up @@ -144,10 +216,7 @@ func (r *TenantResource) Read(ctx context.Context, req resource.ReadRequest, res
return
}

data.Name = types.StringValue(tenant.Name)
if tenant.Description != "" {
data.Description = types.StringValue(tenant.Description)
}
tenantToData(tenant, &data)

// Save updated data into Terraform state
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
Expand All @@ -170,15 +239,13 @@ func (r *TenantResource) Update(ctx context.Context, req resource.UpdateRequest,
// resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to update tenant, got error: %s", err))
// return
// }
err := r.chirpstack.UpdateTenant(ctx, &api.Tenant{
Id: data.Id.ValueString(),
Name: data.Name.ValueString(),
Description: data.Description.ValueString(),
})
tenant := tenantFromData(&data)
err := r.chirpstack.UpdateTenant(ctx, tenant)
if err != nil {
resp.Diagnostics.AddError("Chirpstack Error", fmt.Sprintf("Unable to update tenant, got error: %s", err))
return
}
tenantToData(tenant, &data)

// Save updated data into Terraform state
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
Expand Down
2 changes: 2 additions & 0 deletions internal/provider/tenant_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func TestAccTenantResource(t *testing.T) {
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrSet("chirpstack_tenant.test", "id"),
resource.TestCheckResourceAttr("chirpstack_tenant.test", "name", "one"),
resource.TestCheckResourceAttr("chirpstack_tenant.test", "can_have_gateways", "true"),
),
},
// ImportState testing
Expand All @@ -45,6 +46,7 @@ func testAccTenantResourceConfig(name string) string {
return fmt.Sprintf(`
resource "chirpstack_tenant" "test" {
name = %[1]q
can_have_gateways = true
}
`, name)
}

0 comments on commit 3e32b90

Please sign in to comment.