This commit is contained in:
2026-06-19 17:45:18 +03:00
parent c00c608ce9
commit 89c77ddcbe
1324 changed files with 199523 additions and 1 deletions

View File

@@ -0,0 +1,36 @@
package logicalports
import (
"context"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
func dataSourceLogicalPortRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
logicalPort, err := utilityLogicalPortCheckPresence(ctx, d, m)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
flattenLogicalPort(d, logicalPort)
d.SetId(logicalPort.ID)
return nil
}
func DataSourceLogicalPort() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
ReadContext: dataSourceLogicalPortRead,
Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s,
Default: &constants.Timeout60s,
},
Schema: dataSourceLogicalPortSchemaMake(),
}
}

View File

@@ -0,0 +1,35 @@
package logicalports
import (
"context"
"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 dataSourceLogicalPortByUniqueIDRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
logicalPort, err := utilityLogicalPortByUniqueIDCheckPresence(ctx, d, m)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
flattenLogicalPort(d, logicalPort)
d.SetId(logicalPort.ID)
return nil
}
func DataSourceLogicalPortByUniqueID() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
ReadContext: dataSourceLogicalPortByUniqueIDRead,
Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s,
Default: &constants.Timeout60s,
},
Schema: dataSourceLogicalPortByUniqueIDSchemaMake(),
}
}

View File

@@ -0,0 +1,39 @@
package logicalports
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 dataSourceLogicalPortListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
logicalPortList, err := utilityLogicalPortListCheckPresence(ctx, d, m)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
id := uuid.New()
d.SetId(id.String())
d.Set("items", flattenLogicalPortList(logicalPortList))
return nil
}
func DataSourceLogicalPortList() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
ReadContext: dataSourceLogicalPortListRead,
Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s,
Default: &constants.Timeout60s,
},
Schema: dataSourceLogicalPortListSchemaMake(),
}
}

View File

@@ -0,0 +1,150 @@
package logicalports
import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/logicalports"
)
func flattenLogicalPortResource(d *schema.ResourceData, logicalPort *logicalports.LogicalPort) {
d.Set("id", logicalPort.ID)
d.Set("access_group_id", logicalPort.AccessGroupID)
d.Set("access_group_name", logicalPort.AccessGroupName)
d.Set("adapter_mac", logicalPort.AdapterMAC)
d.Set("address_detection", logicalPort.AddressDetection)
d.Set("description", logicalPort.Description)
d.Set("display_name", logicalPort.DisplayName)
d.Set("enabled", logicalPort.Enabled)
d.Set("external_network_id", logicalPort.ExternalNetworkID)
d.Set("hypervisor", logicalPort.Hypervisor)
d.Set("hypervisor_display_name", logicalPort.HypervisorDisplayName)
d.Set("live_migration_target_hv", logicalPort.LiveMigrationTargetHV)
d.Set("status", flattenStatus(logicalPort.Status))
d.Set("unique_identifier", logicalPort.UniqueIdentifier)
d.Set("version_id", logicalPort.VersionID)
d.Set("bindings", flattenBindings(logicalPort.Bindings))
d.Set("labels", flattenLabels(logicalPort.Labels))
d.Set("created_at", logicalPort.CreatedAt)
}
func flattenLogicalPortList(lpl *logicalports.LogicalPortsList) []map[string]interface{} {
res := make([]map[string]interface{}, 0, len(lpl.Ports))
for _, v := range lpl.Ports {
temp := map[string]interface{}{
"id": v.ID,
"access_group_id": v.AccessGroupID,
"access_group_name": v.AccessGroupName,
"adapter_mac": v.AdapterMAC,
"address_detection": v.AddressDetection,
"description": v.Description,
"display_name": v.DisplayName,
"enabled": v.Enabled,
"hypervisor": v.Hypervisor,
"hypervisor_display_name": v.HypervisorDisplayName,
"external_network_id": v.ExternalNetworkID,
"live_migration_target_hv": v.LiveMigrationTargetHV,
"status": flattenStatus(v.Status),
"unique_identifier": v.UniqueIdentifier,
"version_id": v.VersionID,
"bindings": flattenBindings(v.Bindings),
"labels": flattenLabels(v.Labels),
"created_at": v.CreatedAt,
"updated_at": v.UpdatedAt,
}
res = append(res, temp)
}
return res
}
func flattenLogicalPort(d *schema.ResourceData, logicalPort *logicalports.LogicalPort) {
d.Set("id", logicalPort.ID)
d.Set("access_group_id", logicalPort.AccessGroupID)
d.Set("access_group_name", logicalPort.AccessGroupName)
d.Set("adapter_mac", logicalPort.AdapterMAC)
d.Set("address_detection", logicalPort.AddressDetection)
d.Set("description", logicalPort.Description)
d.Set("display_name", logicalPort.DisplayName)
d.Set("enabled", logicalPort.Enabled)
d.Set("external_network_id", logicalPort.ExternalNetworkID)
d.Set("hypervisor", logicalPort.Hypervisor)
d.Set("hypervisor_display_name", logicalPort.HypervisorDisplayName)
d.Set("live_migration_target_hv", logicalPort.LiveMigrationTargetHV)
d.Set("status", flattenStatus(logicalPort.Status))
d.Set("unique_identifier", logicalPort.UniqueIdentifier)
d.Set("version_id", logicalPort.VersionID)
d.Set("bindings", flattenBindings(logicalPort.Bindings))
d.Set("labels", flattenLabels(logicalPort.Labels))
d.Set("created_at", logicalPort.CreatedAt)
d.Set("updated_at", logicalPort.UpdatedAt)
}
func flattenLabels(labels logicalports.Labels) []map[string]interface{} {
if labels.VMID == "" && labels.VMName == "" {
return []map[string]interface{}{}
}
return []map[string]interface{}{
{
"vm_id": labels.VMID,
"vm_name": labels.VMName,
},
}
}
func flattenBindings(bindings logicalports.Bindings) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"id": bindings.ID,
"segment_id": bindings.SegmentID,
"segment_display_name": bindings.SegmentDisplayName,
"port_security": bindings.PortSecurity,
"address_detection": bindings.AddressDetection,
"version_id": bindings.VersionID,
"created_at": bindings.CreatedAt,
"updated_at": bindings.UpdatedAt,
"logical_port_addresses": flattenLogicalPortAddresses(bindings.LogicalPortAddresses),
}
res = append(res, temp)
return res
}
func flattenLogicalPortAddresses(addrs []logicalports.LogicalPortAddress) []map[string]interface{} {
res := make([]map[string]interface{}, 0, len(addrs))
for _, a := range addrs {
res = append(res, map[string]interface{}{
"ip": a.IP,
"ip_type": a.IPType,
"mac": a.MAC,
"id": a.ID,
"logical_port_id": a.LogicalPortID,
"assigned_at": a.AssignedAt,
"is_discovered": a.IsDiscovered,
"is_primary": a.IsPrimary,
})
}
return res
}
func flattenStatus(status logicalports.Status) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"operation_status": status.OperationStatus,
"hypervisor_status": status.HypervisorStatus,
"hypervisors": flattenHypervisors(status.Hypervisors),
}
res = append(res, temp)
return res
}
func flattenHypervisors(hv []logicalports.HypervisorStatus) []map[string]interface{} {
res := make([]map[string]interface{}, 0, len(hv))
for _, v := range hv {
temp := map[string]interface{}{
"operation_status": v.OperationStatus,
"name": v.Name,
"display_name": v.DisplayName,
"hypervisor_status": v.HypervisorStatus,
"synced_at": v.SyncedAt,
}
res = append(res, temp)
}
return res
}

View File

@@ -0,0 +1,283 @@
package logicalports
import (
"context"
"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/sdn/logicalports"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
)
func resourceLogicalPortCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceLogicalPortCreate: called logical port with name %s",
d.Get("display_name").(string))
c := m.(*controller.ControllerCfg)
req := logicalports.CreateRequest{
AccessGroupID: d.Get("access_group_id").(string),
Description: d.Get("description").(string),
DisplayName: d.Get("display_name").(string),
Enabled: d.Get("enabled").(bool),
Hypervisor: d.Get("hypervisor").(string),
PortSecurity: d.Get("port_security").(bool),
SegmentID: d.Get("segment_id").(string),
}
if adapterMAC, ok := d.GetOk("adapter_mac"); ok {
req.AdapterMAC = adapterMAC.(string)
}
if uniqueID, ok := d.GetOk("unique_identifier"); ok {
req.UniqueIdentifier = uniqueID.(string)
}
if labelsRaw, ok := d.GetOk("labels"); ok {
labelsList := labelsRaw.([]interface{})
if len(labelsList) > 0 {
labelsMap := labelsList[0].(map[string]interface{})
req.Labels = logicalports.CreateLabels{
VMID: labelsMap["vm_id"].(string),
VMName: labelsMap["vm_name"].(string),
}
}
}
if logicalPortAddresses, ok := d.GetOk("logical_port_addresses"); ok {
logicalPortAddressesList := logicalPortAddresses.([]interface{})
logicalPortsAddressesArr := make([]logicalports.LogicalPortAddress, 0)
for _, logicalPortAddressRaw := range logicalPortAddressesList {
logicalPortAddressMap := logicalPortAddressRaw.(map[string]interface{})
logicalPortAddress := logicalports.LogicalPortAddress{
IP: logicalPortAddressMap["ip"].(string),
IPType: logicalPortAddressMap["ip_type"].(string),
IsPrimary: logicalPortAddressMap["is_primary"].(bool),
}
if isDiscovered, ok := logicalPortAddressMap["is_discovered"]; ok {
logicalPortAddress.IsDiscovered = isDiscovered.(bool)
}
if mac, ok := logicalPortAddressMap["mac"]; ok {
logicalPortAddress.MAC = mac.(string)
}
logicalPortsAddressesArr = append(logicalPortsAddressesArr, logicalPortAddress)
}
req.LogicalPortAddresses = logicalPortsAddressesArr
}
logicalPort, err := c.SDN().LogicalPorts().Create(ctx, req)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
d.SetId(logicalPort.ID)
return resourceLogicalPortRead(ctx, d, m)
}
func resourceLogicalPortRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceLogicalPortRead: called logical port with id %s", d.Id())
logicalPort, err := utilityLogicalPortCheckPresence(ctx, d, m)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
flattenLogicalPortResource(d, logicalPort)
d.SetId(logicalPort.ID)
return nil
}
func resourceLogicalPortUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceLogicalPortUpdate: called logical port with id %s", d.Id())
c := m.(*controller.ControllerCfg)
migrate := d.Get("migrate").(bool)
req := logicalports.UpdateRequest{
LogicalPortID: d.Id(),
VersionID: uint64(d.Get("version_id").(int)),
AdapterMAC: d.Get("adapter_mac").(string),
Description: d.Get("description").(string),
DisplayName: d.Get("display_name").(string),
Enabled: d.Get("enabled").(bool),
PortSecurity: d.Get("port_security").(bool),
SegmentID: d.Get("segment_id").(string),
}
if !migrate {
req.Hypervisor = d.Get("hypervisor").(string)
} else {
old, _ := d.GetChange("hypervisor")
req.Hypervisor = old.(string)
}
if d.HasChange("labels") {
if labelsRaw, ok := d.GetOk("labels"); ok {
labelsList := labelsRaw.([]interface{})
if len(labelsList) > 0 {
labelsMap := labelsList[0].(map[string]interface{})
req.Labels = logicalports.UpdateLabels{
VMID: labelsMap["vm_id"].(string),
VMName: labelsMap["vm_name"].(string),
}
}
}
}
if d.HasChange("logical_port_addresses") {
oldAddresses, newAddresses := d.GetChange("logical_port_addresses")
oldAddressesList := oldAddresses.([]interface{})
newAddressesList := newAddresses.([]interface{})
oldAddressesMap := make(map[string]logicalports.LogicalPortAddress)
for _, oldAddressRaw := range oldAddressesList {
logicalPortAddressMap := oldAddressRaw.(map[string]interface{})
logicalPortAddress := logicalports.LogicalPortAddress{
IP: logicalPortAddressMap["ip"].(string),
IPType: logicalPortAddressMap["ip_type"].(string),
IsPrimary: logicalPortAddressMap["is_primary"].(bool),
}
if isDiscovered, ok := logicalPortAddressMap["is_discovered"]; ok {
logicalPortAddress.IsDiscovered = isDiscovered.(bool)
}
if mac, ok := logicalPortAddressMap["mac"]; ok {
logicalPortAddress.MAC = mac.(string)
}
oldAddressesMap[logicalPortAddress.IP] = logicalPortAddress
}
newAddressesMap := make(map[string]logicalports.LogicalPortAddress)
for _, newAddressRaw := range newAddressesList {
logicalPortAddressMap := newAddressRaw.(map[string]interface{})
logicalPortAddress := logicalports.LogicalPortAddress{
IP: logicalPortAddressMap["ip"].(string),
IPType: logicalPortAddressMap["ip_type"].(string),
IsPrimary: logicalPortAddressMap["is_primary"].(bool),
}
if isDiscovered, ok := logicalPortAddressMap["is_discovered"]; ok {
logicalPortAddress.IsDiscovered = isDiscovered.(bool)
}
if mac, ok := logicalPortAddressMap["mac"]; ok {
logicalPortAddress.MAC = mac.(string)
}
newAddressesMap[logicalPortAddress.IP] = logicalPortAddress
}
removeAddresses := make([]string, 0)
for addressIP := range oldAddressesMap {
if _, exists := newAddressesMap[addressIP]; !exists {
removeAddresses = append(removeAddresses, addressIP)
}
}
req.RemoveAddresses = removeAddresses
for addressIP, address := range newAddressesMap {
if oldAddressIP, exists := oldAddressesMap[addressIP]; !exists || address != oldAddressIP {
if !exists {
logicalPortAddress := logicalports.AddAddress{
IP: address.IP,
IPType: address.IPType,
IsPrimary: address.IsPrimary,
IsDiscovered: address.IsDiscovered,
MAC: address.MAC,
}
req.AddAddresses = append(req.AddAddresses, logicalPortAddress)
} else if address != oldAddressIP {
logicalPortAddress := logicalports.UpdateAddress{
IP: address.IP,
IPType: address.IPType,
IsPrimary: address.IsPrimary,
IsDiscovered: address.IsDiscovered,
MAC: address.MAC,
}
req.UpdateAddresses = append(req.UpdateAddresses, logicalPortAddress)
}
}
}
}
_, err := c.SDN().LogicalPorts().Update(ctx, req)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
if migrate {
if targetHV, ok := d.GetOk("hypervisor"); ok {
// Re-read version_id
lp, err := utilityLogicalPortCheckPresence(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
migrateReq := logicalports.MigrateStartRequest{
LogicalPortID: d.Id(),
VersionID: lp.VersionID,
TargetHypervisor: targetHV.(string),
}
_, err = c.SDN().LogicalPorts().StartMigrate(ctx, migrateReq)
if err != nil {
return diag.FromErr(err)
}
// to prevent drift on the next plan
diags := resourceLogicalPortRead(ctx, d, m)
if diags.HasError() {
return diags
}
d.Set("hypervisor", targetHV.(string))
return diags
}
}
return resourceLogicalPortRead(ctx, d, m)
}
func resourceLogicalPortDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceLogicalPortDelete: called logical port with id %s", d.Id())
c := m.(*controller.ControllerCfg)
req := logicalports.DeleteRequest{
ID: d.Id(),
Version: uint64(d.Get("version_id").(int)),
}
if force, ok := d.GetOk("force"); ok {
req.Force = force.(bool)
}
_, err := c.SDN().LogicalPorts().Delete(ctx, req)
if err != nil {
return diag.FromErr(err)
}
d.SetId("")
return nil
}
func ResourceLogicalPort() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
CreateContext: resourceLogicalPortCreate,
ReadContext: resourceLogicalPortRead,
UpdateContext: resourceLogicalPortUpdate,
DeleteContext: resourceLogicalPortDelete,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Timeouts: &schema.ResourceTimeout{
Create: &constants.Timeout600s,
Read: &constants.Timeout300s,
Update: &constants.Timeout600s,
Delete: &constants.Timeout300s,
Default: &constants.Timeout300s,
},
Schema: resourceLogicalPortSchemaMake(),
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,30 @@
package logicalports
import (
"context"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/logicalports"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
)
func utilityLogicalPortCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*logicalports.LogicalPort, error) {
c := m.(*controller.ControllerCfg)
req := logicalports.GetRequest{
ID: d.Id(),
}
if d.Id() != "" {
req.ID = d.Id()
} else {
req.ID = d.Get("logical_port_id").(string)
}
logicalPort, err := c.SDN().LogicalPorts().Get(ctx, req)
if err != nil {
return nil, err
}
return logicalPort, nil
}

View File

@@ -0,0 +1,30 @@
package logicalports
import (
"context"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/logicalports"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
)
func utilityLogicalPortByUniqueIDCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*logicalports.LogicalPort, error) {
c := m.(*controller.ControllerCfg)
req := logicalports.GetByUniqueIdentifierRequest{
ID: d.Id(),
}
if d.Id() != "" {
req.ID = d.Id()
} else {
req.ID = d.Get("unique_identifier").(string)
}
logicalPort, err := c.SDN().LogicalPorts().GetByUniqueIdentifier(ctx, req)
if err != nil {
return nil, err
}
return logicalPort, nil
}

View File

@@ -0,0 +1,85 @@
package logicalports
import (
"context"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/logicalports"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
)
func utilityLogicalPortListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*logicalports.LogicalPortsList, error) {
c := m.(*controller.ControllerCfg)
req := logicalports.ListRequest{}
if accessGroupID, ok := d.GetOk("access_group_id"); ok {
req.AccessGroupID = accessGroupID.(string)
}
if segmentID, ok := d.GetOk("segment_id"); ok {
req.SegmentID = segmentID.(string)
}
if segmentDisplayName, ok := d.GetOk("segment_display_name"); ok {
req.SegmentDisplayName = segmentDisplayName.(string)
}
if externalNetworkID, ok := d.GetOk("external_network_id"); ok {
req.ExternalNetworkID = externalNetworkID.(string)
}
if uniqueID, ok := d.GetOk("unique_identifier"); ok {
req.UniqueIdentifier = uniqueID.(string)
}
if displayName, ok := d.GetOk("display_name"); ok {
req.DisplayName = displayName.(string)
}
if adapterMAC, ok := d.GetOk("adapter_mac"); ok {
req.AdapterMAC = adapterMAC.(string)
}
if hypervisor, ok := d.GetOk("hypervisor"); ok {
req.Hypervisor = hypervisor.(string)
}
if hypervisorDisplayName, ok := d.GetOk("hypervisor_display_name"); ok {
req.HypervisorDisplayName = hypervisorDisplayName.(string)
}
if liveMigrationTargetHV, ok := d.GetOk("live_migration_target_hv"); ok {
req.LiveMigrationTargetHv = liveMigrationTargetHV.(string)
}
if portSecurity, ok := d.GetOk("port_security"); ok {
req.PortSecurity = portSecurity.(bool)
}
if addressDetection, ok := d.GetOk("address_detection"); ok {
req.AddressDetection = addressDetection.(bool)
}
if enabled, ok := d.GetOk("enabled"); ok {
req.Enabled = enabled.(bool)
}
if createdFrom, ok := d.GetOk("created_from"); ok {
req.CreatedFrom = createdFrom.(string)
}
if createdTo, ok := d.GetOk("created_to"); ok {
req.CreatedTo = createdTo.(string)
}
if page, ok := d.GetOk("page"); ok {
req.Page = uint64(page.(int))
}
if perPage, ok := d.GetOk("per_page"); ok {
req.PerPage = uint64(perPage.(int))
}
if sortBy, ok := d.GetOk("sort_by"); ok {
req.SortBy = sortBy.(string)
}
if sortOrder, ok := d.GetOk("sort_order"); ok {
req.SortOrder = sortOrder.(string)
}
if operationStatus, ok := d.GetOk("operation_status"); ok {
req.OperationStatus = operationStatus.(string)
}
if hypervisorStatus, ok := d.GetOk("hypervisor_status"); ok {
req.HypervisorStatus = hypervisorStatus.(string)
}
logicalPortList, err := c.SDN().LogicalPorts().List(ctx, req)
if err != nil {
return nil, err
}
return logicalPortList, nil
}