This commit is contained in:
2025-11-18 16:20:26 +03:00
parent 4b3f21d9be
commit e42fbcef39
397 changed files with 17560 additions and 1501 deletions

View File

@@ -0,0 +1,38 @@
package secgroup
import (
"context"
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
)
func dataSourceSecurityGroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
securityGroup, err := utilitySecurityGroupCheckPresence(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
id := uuid.New()
d.SetId(id.String())
flattenSecurityGroup(d, securityGroup)
return nil
}
func DataSourceSecurityGroup() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
ReadContext: dataSourceSecurityGroupRead,
Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s,
Default: &constants.Timeout60s,
},
Schema: dataSourceSecurityGroupSchemaMake(),
}
}

View File

@@ -0,0 +1,40 @@
package secgroup
import (
"context"
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
)
func dataSourceSecurityGroupListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
storagePolicyList, err := utilitySecurityGroupListCheckPresence(ctx, d, m)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
id := uuid.New()
d.SetId(id.String())
d.Set("items", flattenSecurityGroupList(storagePolicyList))
d.Set("entry_count", storagePolicyList.EntryCount)
return nil
}
func DataSourceSecurityGroupList() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
ReadContext: dataSourceSecurityGroupListRead,
Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s,
Default: &constants.Timeout60s,
},
Schema: dataSourceSecurityGroupListSchemaMake(),
}
}

View File

@@ -0,0 +1,68 @@
package secgroup
import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/secgroup"
)
func flattenSecurityGroupResource(d *schema.ResourceData, securityGroup *secgroup.RecordSecurityGroup) {
d.Set("security_group_id", securityGroup.ID)
d.Set("account_id", securityGroup.AccountID)
d.Set("name", securityGroup.Name)
d.Set("description", securityGroup.Description)
d.Set("rules", flattenRules(securityGroup.Rules))
d.Set("created_at", securityGroup.CreatedAt)
d.Set("created_by", securityGroup.CreatedBy)
d.Set("updated_at", securityGroup.UpdatedAt)
d.Set("updated_by", securityGroup.UpdatedBy)
}
func flattenSecurityGroupList(securityGroupList *secgroup.ListSecurityGroups) []map[string]interface{} {
res := make([]map[string]interface{}, 0, len(securityGroupList.Data))
for _, v := range securityGroupList.Data {
temp := map[string]interface{}{
"account_id": v.AccountID,
"name": v.Name,
"description": v.Description,
"rules": flattenRules(v.Rules),
"created_at": v.CreatedAt,
"created_by": v.CreatedBy,
"security_group_id": v.ID,
"updated_at": v.UpdatedAt,
"updated_by": v.UpdatedBy,
}
res = append(res, temp)
}
return res
}
func flattenSecurityGroup(d *schema.ResourceData, securityGroup *secgroup.RecordSecurityGroup) {
d.Set("security_group_id", securityGroup.ID)
d.Set("account_id", securityGroup.AccountID)
d.Set("name", securityGroup.Name)
d.Set("description", securityGroup.Description)
d.Set("rules", flattenRules(securityGroup.Rules))
d.Set("created_at", securityGroup.CreatedAt)
d.Set("created_by", securityGroup.CreatedBy)
d.Set("updated_at", securityGroup.UpdatedAt)
d.Set("updated_by", securityGroup.UpdatedBy)
}
func flattenRules(rules secgroup.Rules) []map[string]interface{} {
res := make([]map[string]interface{}, 0, len(rules))
for _, rule := range rules {
temp := map[string]interface{}{
"id": rule.ID,
"direction": rule.Direction,
"ethertype": rule.Ethertype,
"protocol": rule.Protocol,
"port_range_min": rule.PortRangeMin,
"port_range_max": rule.PortRangeMax,
"remote_ip_prefix": rule.RemoteIPPrefix,
}
res = append(res, temp)
}
return res
}

View File

@@ -0,0 +1,146 @@
package secgroup
import (
"context"
"strconv"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
log "github.com/sirupsen/logrus"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/secgroup"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc"
)
func resourceSecurityGroupCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceSecurityGroupCreate: called with account ID %d, name %s", uint64(d.Get("account_id").(int)), d.Get("name").(string))
c := m.(*controller.ControllerCfg)
warnings := dc.Warnings{}
accountID := uint64(d.Get("account_id").(int))
name := d.Get("name").(string)
req := secgroup.CreateRequest{
AccountID: accountID,
Name: name,
}
if description, ok := d.GetOk("description"); ok {
req.Description = description.(string)
}
securityGroupID, err := c.CloudAPI().SecurityGroup().Create(ctx, req)
if err != nil {
return diag.FromErr(err)
}
d.SetId(strconv.FormatUint(securityGroupID, 10))
d.Set("security_group_id", securityGroupID)
return append(warnings.Get(), resourceSecurityGroupRead(ctx, d, m)...)
}
func resourceSecurityGroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceSecurityGroupRead: called with with account ID %d", uint64(d.Get("account_id").(int)))
w := dc.Warnings{}
securityGroupItem, err := utilitySecurityGroupCheckPresence(ctx, d, m)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
flattenSecurityGroupResource(d, securityGroupItem)
return w.Get()
}
func resourceSecurityGroupUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
securityGroupID, _ := strconv.ParseUint(d.Id(), 10, 64)
log.Debugf("resourceSecurityGroupUpdate: called security group with id %d", securityGroupID)
c := m.(*controller.ControllerCfg)
_, err := utilitySecurityGroupCheckPresence(ctx, d, m)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
_, err = strconv.ParseInt(d.Id(), 10, 64)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
if d.HasChanges("name", "description") {
if err := utilitySecurityGroupHandleHasChanges(ctx, d, c, securityGroupID); err != nil {
return diag.FromErr(err)
}
}
if d.HasChange("rules") {
if err := utilitySecurityGroupUpdateRules(ctx, d, c, securityGroupID); err != nil {
return diag.FromErr(err)
}
}
return resourceSecurityGroupRead(ctx, d, m)
}
func resourceSecurityGroupDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceSecurityGroupDelete: called with id %s", d.Id())
securityGroupItem, err := utilitySecurityGroupCheckPresence(ctx, d, m)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
c := m.(*controller.ControllerCfg)
req := secgroup.DeleteRequest{
SecurityGroupID: securityGroupItem.ID,
}
if _, err := c.CloudAPI().SecurityGroup().Delete(ctx, req); err != nil {
return diag.FromErr(err)
}
d.SetId("")
return nil
}
func ResourceSecurityGroup() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
CreateContext: resourceSecurityGroupCreate,
ReadContext: resourceSecurityGroupRead,
UpdateContext: resourceSecurityGroupUpdate,
DeleteContext: resourceSecurityGroupDelete,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Timeouts: &schema.ResourceTimeout{
Create: &constants.Timeout600s,
Read: &constants.Timeout600s,
Update: &constants.Timeout600s,
Delete: &constants.Timeout600s,
Default: &constants.Timeout600s,
},
Schema: resourceSecurityGroupSchemaMake(),
}
}

View File

@@ -0,0 +1,288 @@
package secgroup
import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)
func resourceSecurityGroupSchemaMake() map[string]*schema.Schema {
res := map[string]*schema.Schema{
"account_id": {
Type: schema.TypeInt,
Required: true,
},
"name": {
Type: schema.TypeString,
Required: true,
},
"description": {
Type: schema.TypeString,
Optional: true,
},
"rules": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"direction": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{"inbound", "outbound"}, true),
},
"ethertype": {
Type: schema.TypeString,
Optional: true,
Default: "IPv4",
ValidateFunc: validation.StringInSlice([]string{"IPv4", "IPv6"}, true),
},
"protocol": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{"icmp", "tcp", "udp"}, true),
},
"port_range_min": {
Type: schema.TypeInt,
Optional: true,
},
"port_range_max": {
Type: schema.TypeInt,
Optional: true,
},
"remote_ip_prefix": {
Type: schema.TypeString,
Optional: true,
},
"id": {
Type: schema.TypeInt,
Computed: true,
},
},
},
},
"security_group_id": {
Type: schema.TypeInt,
Computed: true,
},
"created_at": {
Type: schema.TypeInt,
Computed: true,
},
"updated_at": {
Type: schema.TypeInt,
Computed: true,
},
"created_by": {
Type: schema.TypeString,
Computed: true,
},
"updated_by": {
Type: schema.TypeString,
Computed: true,
},
}
return res
}
func dataSourceSecurityGroupSchemaMake() map[string]*schema.Schema {
res := map[string]*schema.Schema{
"security_group_id": {
Type: schema.TypeInt,
Required: true,
},
"account_id": {
Type: schema.TypeInt,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"description": {
Type: schema.TypeString,
Computed: true,
},
"rules": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeInt,
Computed: true,
},
"direction": {
Type: schema.TypeString,
Computed: true,
},
"ethertype": {
Type: schema.TypeString,
Computed: true,
},
"protocol": {
Type: schema.TypeString,
Computed: true,
},
"port_range_min": {
Type: schema.TypeInt,
Computed: true,
},
"port_range_max": {
Type: schema.TypeInt,
Computed: true,
},
"remote_ip_prefix": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"created_at": {
Type: schema.TypeInt,
Computed: true,
},
"updated_at": {
Type: schema.TypeInt,
Computed: true,
},
"created_by": {
Type: schema.TypeString,
Computed: true,
},
"updated_by": {
Type: schema.TypeString,
Computed: true,
},
}
return res
}
func dataSourceSecurityGroupListSchemaMake() map[string]*schema.Schema {
res := map[string]*schema.Schema{
"page": {
Type: schema.TypeInt,
Optional: true,
},
"size": {
Type: schema.TypeInt,
Optional: true,
},
"by_id": {
Type: schema.TypeInt,
Optional: true,
},
"account_id": {
Type: schema.TypeInt,
Optional: true,
},
"name": {
Type: schema.TypeString,
Optional: true,
},
"desc": {
Type: schema.TypeString,
Optional: true,
},
"sort_by": {
Type: schema.TypeString,
Optional: true,
},
"created_min": {
Type: schema.TypeInt,
Optional: true,
},
"created_max": {
Type: schema.TypeInt,
Optional: true,
},
"updated_min": {
Type: schema.TypeInt,
Optional: true,
},
"updated_max": {
Type: schema.TypeInt,
Optional: true,
},
"items": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"security_group_id": {
Type: schema.TypeInt,
Computed: true,
},
"account_id": {
Type: schema.TypeInt,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"description": {
Type: schema.TypeString,
Computed: true,
},
"rules": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeInt,
Computed: true,
},
"direction": {
Type: schema.TypeString,
Computed: true,
},
"ethertype": {
Type: schema.TypeString,
Computed: true,
},
"protocol": {
Type: schema.TypeString,
Computed: true,
},
"port_range_min": {
Type: schema.TypeInt,
Computed: true,
},
"port_range_max": {
Type: schema.TypeInt,
Computed: true,
},
"remote_ip_prefix": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"created_at": {
Type: schema.TypeInt,
Computed: true,
},
"updated_at": {
Type: schema.TypeInt,
Computed: true,
},
"created_by": {
Type: schema.TypeString,
Computed: true,
},
"updated_by": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"entry_count": {
Type: schema.TypeInt,
Computed: true,
},
}
return res
}

View File

@@ -0,0 +1,95 @@
package secgroup
import (
"context"
"strconv"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
log "github.com/sirupsen/logrus"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/secgroup"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
)
func utilitySecurityGroupCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*secgroup.RecordSecurityGroup, error) {
c := m.(*controller.ControllerCfg)
req := secgroup.GetRequest{}
if d.Id() != "" {
securityGroupID, _ := strconv.ParseUint(d.Id(), 10, 64)
req.SecurityGroupID = securityGroupID
} else {
req.SecurityGroupID = uint64(d.Get("security_group_id").(int))
}
log.Debugf("utilitySecurityGroupCheckPresence: load security group")
securityGroup, err := c.CloudAPI().SecurityGroup().Get(ctx, req)
if err != nil {
return nil, err
}
return securityGroup, nil
}
func utilitySecurityGroupHandleHasChanges(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, securityGroupID uint64) error {
req := secgroup.UpdateRequest{
SecurityGroupID: securityGroupID,
}
if d.HasChange("name") {
name := d.Get("name").(string)
req.Name = name
}
if d.HasChange("description") {
description := d.Get("description").(string)
req.Description = description
}
if _, err := c.CloudAPI().SecurityGroup().Update(ctx, req); err != nil {
return err
}
return nil
}
func utilitySecurityGroupUpdateRules(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, securityGroupID uint64) error {
oldSet, newSet := d.GetChange("rules")
deletedRules := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List()
for _, deletedInterface := range deletedRules {
deletedItem := deletedInterface.(map[string]interface{})
ruleID := uint64(deletedItem["id"].(int))
req := secgroup.DeleteRuleRequest{
SecurityGroupID: securityGroupID,
RuleID: ruleID,
}
if _, err := c.CloudAPI().SecurityGroup().DeleteRule(ctx, req); err != nil {
return err
}
}
addedRules := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List()
for _, addedInterface := range addedRules {
addedItem := addedInterface.(map[string]interface{})
direction := addedItem["direction"].(string)
ethertype := addedItem["ethertype"].(string)
protocol := addedItem["protocol"].(string)
portRangeMin := uint64(addedItem["port_range_min"].(int))
portRangeMax := uint64(addedItem["port_range_max"].(int))
remoteIPPrefix := addedItem["remote_ip_prefix"].(string)
req := secgroup.CreateRuleRequest{
SecurityGroupID: securityGroupID,
Direction: direction,
Ethertype: ethertype,
Protocol: protocol,
PortRangeMin: portRangeMin,
PortRangeMax: portRangeMax,
RemoteIPPrefix: remoteIPPrefix,
}
if _, err := c.CloudAPI().SecurityGroup().CreateRule(ctx, req); err != nil {
return err
}
}
return nil
}

View File

@@ -0,0 +1,60 @@
package secgroup
import (
"context"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
log "github.com/sirupsen/logrus"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/secgroup"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
)
func utilitySecurityGroupListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*secgroup.ListSecurityGroups, error) {
c := m.(*controller.ControllerCfg)
req := secgroup.ListRequest{}
if size, ok := d.GetOk("size"); ok {
req.Size = uint64(size.(int))
}
if page, ok := d.GetOk("page"); ok {
req.Page = uint64(page.(int))
}
if byID, ok := d.GetOk("by_id"); ok {
req.ByID = uint64(byID.(int))
}
if accountID, ok := d.GetOk("account_id"); ok {
req.AccountID = uint64(accountID.(int))
}
if name, ok := d.GetOk("name"); ok {
req.Name = name.(string)
}
if desc, ok := d.GetOk("desc"); ok {
req.Description = desc.(string)
}
if sortBy, ok := d.GetOk("sort_by"); ok {
req.SortBy = sortBy.(string)
}
if createdMin, ok := d.GetOk("created_min"); ok {
req.CreatedMin = uint64(createdMin.(int))
}
if createdMax, ok := d.GetOk("created_max"); ok {
req.CreatedMax = uint64(createdMax.(int))
}
if updatedMin, ok := d.GetOk("updated_min"); ok {
req.UpdatedMin = uint64(updatedMin.(int))
}
if updatedMax, ok := d.GetOk("updated_max"); ok {
req.UpdatedMax = uint64(updatedMax.(int))
}
log.Debugf("utilitySecurityGroupListCheckPresence: load storage policy list")
securityGroupList, err := c.CloudAPI().SecurityGroup().List(ctx, req)
if err != nil {
return nil, err
}
return securityGroupList, nil
}