Skip to content

feat!: add support for private subnets for dedicated servers#376

Open
Disaxy wants to merge 2 commits intoselectel:masterfrom
Disaxy:dedicated_private_subnet_v1
Open

feat!: add support for private subnets for dedicated servers#376
Disaxy wants to merge 2 commits intoselectel:masterfrom
Disaxy:dedicated_private_subnet_v1

Conversation

@Disaxy
Copy link

@Disaxy Disaxy commented Feb 17, 2026

  1. Добавлены атрибуты с IP-адресами созданного сервера для ресурса
    dedicated_server_v1.
  2. Добавлен аргумент для ресурса dedicated_server_v1 для возможности создания
    сервера сразу с приватным vlan.
  3. Добавлен атрибут для ресурса dedicated_server_v1, отражающий наличие
    приватного VLAN на сервере.
  4. Добавлен источник данных для работы с приватными подсетями.
  5. Добавлены параметры для подключения приватной подсети к серверу для
    ресурса dedicated_server_v1.
  6. Добавлен ресурс для приватных подсетей.
  7. Убраны из списка вывода data source dedicated_location_v1 локации, у которых
    visibility = “admin_only”.

selectel/dedicated-go#2

Jira Issue: COOPERATION-97008

}

locationID := d.Get("location_id").(string)
vlan := d.Get("vlan").(string)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vlan имеет ограничения, хорошо бы проверять, что номер влана не выходит за пределы [1..4095]. А лучше вообще сделать его int и в строку превращать уже ближе к формированию query

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

если делать интом проверку можно повесить в ресурсе

validation.IntBetween(1, 4095)

я не эксперт, но гугл подсказывает что 4095 зарезерирован. тут нужна доп верификация. возможно итоговая валидация должна быть

validation.IntBetween(1, 4094)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Да, у нас есть валидация на переданное значение. Range(1,3499)

ForceNew: true,
Description: "VLAN TAG for the private subnet",
},
"subnet": {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Аналогично тут, стоит добавить валидацию
ex

Computed: true,
Description: "ID of the created private subnet",
},
"location_id": {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Стоит добавить валидацию на то, что это uuid.
можно использовать из стандартного набора хелперов

## Attributes Reference

* `locations` - List of the available locations:
* `locations` - List of the available locations (excluding locations with `visibility = "admin_only"`):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

нужна ли эта информация тут ? Сокрытие admin_only локаций, выглядит как наша служебная история, которую можно не показывать публично, чтобы не соблазнять всех желащих туда постучать.

Type: schema.TypeString,
Computed: true,
},
"reserved_ip": {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reserved_ip -> reserved_ips, раз это список, а не одиночная сущность

}

// Define private IP ranges
privateRanges := []struct {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Почему бы тут не использовать стандартный метод из [netip](https://cs.opensource.google/go/go/+/refs/tags/go1.26.0:src/net/netip/netip.go;l=640) ?


"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
dedicated "github.com/selectel/dedicated-go/pkg/v2"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Обнови, пожалуйста, версию dedicated-go доv2.0.0

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Обновлено в d5ea6ef

@milkrage milkrage changed the title Stage 1 feat: add support for local subnets Feb 25, 2026
@milkrage milkrage changed the title feat: add support for local subnets feat(dedicated_server_v1): add support for local subnets Feb 25, 2026
if err != nil {
return diag.FromErr(err)
}
if err := d.Set("subnets", subnetsFlatten); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Думаю лучше использовать одинаковый подход к присваиванию ошибок и здесь тоже использовать

err = d.Set("subnets", subnetsFlatten)
if err != nil {
    return diag.FromErr(err)
}

if (filter.subnet == "" || filter.subnet == subnet.Subnet) && (filter.ip == "" || isIPIncluded) {
filteredSubnets = append(filteredSubnets, subnet)

continue
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

После этого continue ничего нет, его можно убрать

for _, network := range nets {
localSubnets, _, err := dsClient.NetworkLocalSubnets(ctx, network.UUID)
if err != nil {
continue // Continue with other networks if one fails
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Точно ли корректно скипать здесь ошибку? Если необходимый ip/subnet находится в network, по которому список subnet получить не удалось, datasource по идее останется пустым, абсолютно непрозрачно по какой причине. Кажется, что ошибку надо обрабатывать и возвращать

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Да, этот метод может вернуть пустой список и 200

Copy link
Contributor

@milkrage milkrage Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Если список будет пустым, то append просто ничего не добавит. Тут проблема с следующем кейсе: мы делаем запрос dsClient.NetworkLocalSubnets, получаем какую-то ошибку (таймаут, например) и не выкидываем эту ошибку выше, мы просто делаем continue. Со стороны выглядит странно.

Comment on lines +94 to +97
// IsPrivateSubnet validates if the provided CIDR belongs to private IP ranges.
func IsPrivateSubnet(cidr string) bool {
return validatePrivateSubnet(cidr) == nil
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Эта функция нигде не используется кроме тестов

Comment on lines +32 to +35
"ip": {
Type: schema.TypeString,
Optional: true,
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

здесь можно использовать

ValidateFunc: validation.IsIPAddress

то же самое применимо для всех IP

}

locationID := d.Get("location_id").(string)
vlan := d.Get("vlan").(string)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

если делать интом проверку можно повесить в ресурсе

validation.IntBetween(1, 4095)

я не эксперт, но гугл подсказывает что 4095 зарезерирован. тут нужна доп верификация. возможно итоговая валидация должна быть

validation.IntBetween(1, 4094)

}

func getDedicatedClient(d *schema.ResourceData, meta interface{}) (*dedicated.ServiceClient, diag.Diagnostics) {
func getDedicatedClient(d *schema.ResourceData, meta interface{}, withProjectScope bool) (*dedicated.ServiceClient, diag.Diagnostics) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Судя по swagger спецификации, Dedicated Servers API, поддерживает для всех необходимых методов project scope. Это не так?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Все так, выделенные серверы поддерживают project scope во всех методах

Copy link
Contributor

@milkrage milkrage Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тогда необходимо убрать bool флаг из сигнатуры метода и всегда использовать клиент с project scope токеном.

Comment on lines +18 to +46
"project_id": {
Type: schema.TypeString,
Required: true,
},
"filter": {
Type: schema.TypeSet,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"location_id": {
Type: schema.TypeString,
Optional: true,
},
"ip": {
Type: schema.TypeString,
Optional: true,
},
"subnet": {
Type: schema.TypeString,
Optional: true,
},
"vlan": {
Type: schema.TypeString,
Optional: true,
},
},
},
},
Copy link
Contributor

@milkrage milkrage Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Хорошей практикой является валидация пользовательского ввода до отправки запроса в API.

  1. location_id - uuid, в проекте используется метод validate.IsUUID
  2. ip - validate.IIsIPAddress
  3. subnet - validate.IIsCIDR
  4. vlan - validate.IntBetween

Comment on lines -143 to +152
dedicatedServerSchemaKeyPrivateSubnet: {
dedicatedServerSchemaKeyPrivateSubnetID: {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
Copy link
Contributor

@milkrage milkrage Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тут прям очень жестко ломается манифест (будет ошибка unsupported argument для старых манифестов), стоит ли так делать? Возможно нужно старое поле отметить Deprecated флагом и написать, что нужно использовать новые поля? При этом новые поля, это именно новые поля, а не ренейм старых.

@TawR1024, подскажи, пожалуйста, у меня правильное понимание процесса изменения схемы?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Переименования поля опасная операция. Если брать во внимание, что у этого ресурса уже есть пользователи то тут следуте пойти по пути через deprecate старого поля, добавление нового поля.

Также стоит учесть, что если у поля изменилось поведение, а именно добавили поведение ForceNew, то стоит очень хорошо протестировать поведение state в таком случае. Скорее всего, посольку при state refresh значение поля вместо null получит новое значение, то может быть ресурс придётся пересоздать, что нежелательно для серверов.

Comment on lines +47 to +56
## Import

You can import a subnet data source:

```shell
export OS_DOMAIN_NAME=<account_id>
export OS_USERNAME=<username>
export OS_PASSWORD=<password>
export INFRA_PROJECT_ID=<selectel_project_id>
terraform import selectel_dedicated_private_subnet_v1.subnet_ds <subnet_id>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

У data source есть возможность импорта?

@milkrage milkrage changed the title feat(dedicated_server_v1): add support for local subnets feat: add support for private subnets for dedicated servers Feb 26, 2026
objectDedicatedServer = "dedicated-server"
objectOS = "os"
objectLocation = "location"
objectNetwork = "network"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

network для dedicated и для других услуг может быть разным.
Имеет смысл делать более специфичные имена, dedicated-network

@milkrage milkrage changed the title feat: add support for private subnets for dedicated servers feat!: add support for private subnets for dedicated servers Feb 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dedicated dedicated servers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants