feat!: add support for private subnets for dedicated servers#376
feat!: add support for private subnets for dedicated servers#376Disaxy wants to merge 2 commits intoselectel:masterfrom
Conversation
| } | ||
|
|
||
| locationID := d.Get("location_id").(string) | ||
| vlan := d.Get("vlan").(string) |
There was a problem hiding this comment.
vlan имеет ограничения, хорошо бы проверять, что номер влана не выходит за пределы [1..4095]. А лучше вообще сделать его int и в строку превращать уже ближе к формированию query
There was a problem hiding this comment.
если делать интом проверку можно повесить в ресурсе
validation.IntBetween(1, 4095)
я не эксперт, но гугл подсказывает что 4095 зарезерирован. тут нужна доп верификация. возможно итоговая валидация должна быть
validation.IntBetween(1, 4094)
There was a problem hiding this comment.
Да, у нас есть валидация на переданное значение. Range(1,3499)
| ForceNew: true, | ||
| Description: "VLAN TAG for the private subnet", | ||
| }, | ||
| "subnet": { |
| Computed: true, | ||
| Description: "ID of the created private subnet", | ||
| }, | ||
| "location_id": { |
There was a problem hiding this comment.
Стоит добавить валидацию на то, что это uuid.
можно использовать из стандартного набора хелперов
| ## Attributes Reference | ||
|
|
||
| * `locations` - List of the available locations: | ||
| * `locations` - List of the available locations (excluding locations with `visibility = "admin_only"`): |
There was a problem hiding this comment.
нужна ли эта информация тут ? Сокрытие admin_only локаций, выглядит как наша служебная история, которую можно не показывать публично, чтобы не соблазнять всех желащих туда постучать.
| Type: schema.TypeString, | ||
| Computed: true, | ||
| }, | ||
| "reserved_ip": { |
There was a problem hiding this comment.
reserved_ip -> reserved_ips, раз это список, а не одиночная сущность
| } | ||
|
|
||
| // Define private IP ranges | ||
| privateRanges := []struct { |
There was a problem hiding this comment.
Почему бы тут не использовать стандартный метод из [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" |
There was a problem hiding this comment.
Обнови, пожалуйста, версию dedicated-go доv2.0.0
| if err != nil { | ||
| return diag.FromErr(err) | ||
| } | ||
| if err := d.Set("subnets", subnetsFlatten); err != nil { |
There was a problem hiding this comment.
Думаю лучше использовать одинаковый подход к присваиванию ошибок и здесь тоже использовать
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 |
There was a problem hiding this comment.
После этого continue ничего нет, его можно убрать
| for _, network := range nets { | ||
| localSubnets, _, err := dsClient.NetworkLocalSubnets(ctx, network.UUID) | ||
| if err != nil { | ||
| continue // Continue with other networks if one fails |
There was a problem hiding this comment.
Точно ли корректно скипать здесь ошибку? Если необходимый ip/subnet находится в network, по которому список subnet получить не удалось, datasource по идее останется пустым, абсолютно непрозрачно по какой причине. Кажется, что ошибку надо обрабатывать и возвращать
There was a problem hiding this comment.
Да, этот метод может вернуть пустой список и 200
There was a problem hiding this comment.
Если список будет пустым, то append просто ничего не добавит. Тут проблема с следующем кейсе: мы делаем запрос dsClient.NetworkLocalSubnets, получаем какую-то ошибку (таймаут, например) и не выкидываем эту ошибку выше, мы просто делаем continue. Со стороны выглядит странно.
| // IsPrivateSubnet validates if the provided CIDR belongs to private IP ranges. | ||
| func IsPrivateSubnet(cidr string) bool { | ||
| return validatePrivateSubnet(cidr) == nil | ||
| } |
There was a problem hiding this comment.
Эта функция нигде не используется кроме тестов
| "ip": { | ||
| Type: schema.TypeString, | ||
| Optional: true, | ||
| }, |
There was a problem hiding this comment.
здесь можно использовать
ValidateFunc: validation.IsIPAddress
то же самое применимо для всех IP
| } | ||
|
|
||
| locationID := d.Get("location_id").(string) | ||
| vlan := d.Get("vlan").(string) |
There was a problem hiding this comment.
если делать интом проверку можно повесить в ресурсе
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) { |
There was a problem hiding this comment.
Судя по swagger спецификации, Dedicated Servers API, поддерживает для всех необходимых методов project scope. Это не так?
There was a problem hiding this comment.
Все так, выделенные серверы поддерживают project scope во всех методах
There was a problem hiding this comment.
Тогда необходимо убрать bool флаг из сигнатуры метода и всегда использовать клиент с project scope токеном.
| "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, | ||
| }, | ||
| }, | ||
| }, | ||
| }, |
There was a problem hiding this comment.
Хорошей практикой является валидация пользовательского ввода до отправки запроса в API.
location_id- uuid, в проекте используется методvalidate.IsUUIDip-validate.IIsIPAddresssubnet-validate.IIsCIDRvlan-validate.IntBetween
| dedicatedServerSchemaKeyPrivateSubnet: { | ||
| dedicatedServerSchemaKeyPrivateSubnetID: { | ||
| Type: schema.TypeString, | ||
| Optional: true, | ||
| ForceNew: true, | ||
| }, |
There was a problem hiding this comment.
Тут прям очень жестко ломается манифест (будет ошибка unsupported argument для старых манифестов), стоит ли так делать? Возможно нужно старое поле отметить Deprecated флагом и написать, что нужно использовать новые поля? При этом новые поля, это именно новые поля, а не ренейм старых.
@TawR1024, подскажи, пожалуйста, у меня правильное понимание процесса изменения схемы?
There was a problem hiding this comment.
Переименования поля опасная операция. Если брать во внимание, что у этого ресурса уже есть пользователи то тут следуте пойти по пути через deprecate старого поля, добавление нового поля.
Также стоит учесть, что если у поля изменилось поведение, а именно добавили поведение ForceNew, то стоит очень хорошо протестировать поведение state в таком случае. Скорее всего, посольку при state refresh значение поля вместо null получит новое значение, то может быть ресурс придётся пересоздать, что нежелательно для серверов.
| ## 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> |
There was a problem hiding this comment.
У data source есть возможность импорта?
| objectDedicatedServer = "dedicated-server" | ||
| objectOS = "os" | ||
| objectLocation = "location" | ||
| objectNetwork = "network" |
There was a problem hiding this comment.
network для dedicated и для других услуг может быть разным.
Имеет смысл делать более специфичные имена, dedicated-network
dedicated_server_v1.
сервера сразу с приватным vlan.
приватного VLAN на сервере.
ресурса dedicated_server_v1.
visibility = “admin_only”.
selectel/dedicated-go#2
Jira Issue: COOPERATION-97008