feat: add SNMP community string support to organization resource

- Add snmp_community field to Organization struct (client.go)
- Add snmp_community attribute to organization resource schema
- Mark as Optional and Sensitive in Terraform
- Include in Create and Update operations
- Only settable by organization owners (enforced by API)

Example usage:
  resource "towerops_organization" "main" {
    name           = "My Organization"
    use_sites      = true
    snmp_community = "public"
  }
This commit is contained in:
Graham McIntire 2026-03-10 13:59:54 -05:00
parent 1ccf9ce30a
commit 96bb767c83
No known key found for this signature in database
2 changed files with 27 additions and 8 deletions

View file

@ -70,10 +70,11 @@ type Device struct {
// Organization represents a TowerOps organization. // Organization represents a TowerOps organization.
type Organization struct { type Organization struct {
ID string `json:"id,omitempty"` ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`
Slug string `json:"slug,omitempty"` Slug string `json:"slug,omitempty"`
UseSites bool `json:"use_sites"` UseSites bool `json:"use_sites"`
SnmpCommunity string `json:"snmp_community,omitempty"`
} }
// organizationResponse wraps the API response for organization endpoints. // organizationResponse wraps the API response for organization endpoints.

View file

@ -20,10 +20,11 @@ type OrganizationResource struct {
// OrganizationResourceModel describes the resource data model. // OrganizationResourceModel describes the resource data model.
type OrganizationResourceModel struct { type OrganizationResourceModel struct {
ID types.String `tfsdk:"id"` ID types.String `tfsdk:"id"`
Name types.String `tfsdk:"name"` Name types.String `tfsdk:"name"`
Slug types.String `tfsdk:"slug"` Slug types.String `tfsdk:"slug"`
UseSites types.Bool `tfsdk:"use_sites"` UseSites types.Bool `tfsdk:"use_sites"`
SnmpCommunity types.String `tfsdk:"snmp_community"`
} }
// NewOrganizationResource creates a new organization resource. // NewOrganizationResource creates a new organization resource.
@ -59,6 +60,11 @@ func (r *OrganizationResource) Schema(ctx context.Context, req resource.SchemaRe
Description: "Whether the organization uses sites to group devices. When true, devices are organized under sites. When false, devices belong directly to the organization.", Description: "Whether the organization uses sites to group devices. When true, devices are organized under sites. When false, devices belong directly to the organization.",
Required: true, Required: true,
}, },
"snmp_community": schema.StringAttribute{
Description: "Default SNMP community string for devices. Can only be set by organization owners.",
Optional: true,
Sensitive: true,
},
}, },
} }
} }
@ -97,6 +103,11 @@ func (r *OrganizationResource) Create(ctx context.Context, req resource.CreateRe
org.Name = data.Name.ValueString() org.Name = data.Name.ValueString()
} }
// Include SNMP community if provided
if !data.SnmpCommunity.IsNull() && !data.SnmpCommunity.IsUnknown() {
org.SnmpCommunity = data.SnmpCommunity.ValueString()
}
updated, err := r.client.UpdateOrganization(org) updated, err := r.client.UpdateOrganization(org)
if err != nil { if err != nil {
resp.Diagnostics.AddError("Failed to update organization", err.Error()) resp.Diagnostics.AddError("Failed to update organization", err.Error())
@ -107,6 +118,7 @@ func (r *OrganizationResource) Create(ctx context.Context, req resource.CreateRe
data.Name = types.StringValue(updated.Name) data.Name = types.StringValue(updated.Name)
data.Slug = types.StringValue(updated.Slug) data.Slug = types.StringValue(updated.Slug)
data.UseSites = types.BoolValue(updated.UseSites) data.UseSites = types.BoolValue(updated.UseSites)
data.SnmpCommunity = types.StringValue(updated.SnmpCommunity)
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
} }
@ -150,6 +162,11 @@ func (r *OrganizationResource) Update(ctx context.Context, req resource.UpdateRe
org.Name = data.Name.ValueString() org.Name = data.Name.ValueString()
} }
// Include SNMP community if provided
if !data.SnmpCommunity.IsNull() && !data.SnmpCommunity.IsUnknown() {
org.SnmpCommunity = data.SnmpCommunity.ValueString()
}
updated, err := r.client.UpdateOrganization(org) updated, err := r.client.UpdateOrganization(org)
if err != nil { if err != nil {
resp.Diagnostics.AddError("Failed to update organization", err.Error()) resp.Diagnostics.AddError("Failed to update organization", err.Error())
@ -160,6 +177,7 @@ func (r *OrganizationResource) Update(ctx context.Context, req resource.UpdateRe
data.Name = types.StringValue(updated.Name) data.Name = types.StringValue(updated.Name)
data.Slug = types.StringValue(updated.Slug) data.Slug = types.StringValue(updated.Slug)
data.UseSites = types.BoolValue(updated.UseSites) data.UseSites = types.BoolValue(updated.UseSites)
data.SnmpCommunity = types.StringValue(updated.SnmpCommunity)
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
} }