diff --git a/go.mod b/go.mod index 9e9c291c2..5a405a2e1 100644 --- a/go.mod +++ b/go.mod @@ -53,13 +53,13 @@ require ( github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/zclconf/go-cty v1.15.0 // indirect - golang.org/x/crypto v0.31.0 // indirect + golang.org/x/crypto v0.33.0 // indirect golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.33.0 // indirect + golang.org/x/net v0.35.0 // indirect golang.org/x/oauth2 v0.22.0 // indirect - golang.org/x/sync v0.10.0 // indirect - golang.org/x/sys v0.28.0 // indirect - golang.org/x/text v0.21.0 // indirect + golang.org/x/sync v0.11.0 // indirect + golang.org/x/sys v0.30.0 // indirect + golang.org/x/text v0.22.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect diff --git a/go.sum b/go.sum index 448d210a2..565fb7887 100644 --- a/go.sum +++ b/go.sum @@ -172,6 +172,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= +golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= golang.org/x/exp v0.0.0-20230809150735-7b3493d9a819 h1:EDuYyU/MkFXllv9QF9819VlI9a4tzGuCbhG0ExK9o1U= golang.org/x/exp v0.0.0-20230809150735-7b3493d9a819/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= @@ -183,6 +185,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= +golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -190,6 +194,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -204,10 +210,13 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= +golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -215,6 +224,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= diff --git a/ovh/order.go b/ovh/order.go index 1cd1ac284..a75c4641b 100644 --- a/ovh/order.go +++ b/ovh/order.go @@ -244,7 +244,11 @@ func orderCreateFromResource(d *schema.ResourceData, meta interface{}, product s func orderCreate(d *OrderModel, config *Config, product string, waitForCompletion bool) error { if d.OvhSubsidiary.ValueString() == "" { - return fmt.Errorf("ovh_subsidiary is missing from configuration") + subsidiary, err := getOVHSubsidiary(context.Background(), config.OVHClient) + if err != nil { + return fmt.Errorf("ovh_subsidiary is missing from configuration, and it couldn't be fetched automatically: %w", err) + } + d.OvhSubsidiary = types.NewTfStringValue(subsidiary) } if len(d.Plan.Elements()) == 0 { return fmt.Errorf("plan is missing from configuration") @@ -696,3 +700,13 @@ func orderDetailOperations(c *ovh.Client, orderId int64, orderDetailId int64) ([ } return operations, nil } + +func getOVHSubsidiary(ctx context.Context, c *ovh.Client) (string, error) { + var response MeResponse + + if err := c.GetWithContext(ctx, "/me", &response); err != nil { + return "", err + } + + return response.OvhSubsidiary, nil +} diff --git a/ovh/order_cart.go b/ovh/order_cart.go index c90a7832b..3f01d1ea7 100644 --- a/ovh/order_cart.go +++ b/ovh/order_cart.go @@ -406,7 +406,7 @@ func orderCartGenericProductPlanRead(d *schema.ResourceData, meta interface{}) e ) if err := config.OVHClient.Get(endpoint, &res); err != nil { - return fmt.Errorf("Error calling Get %s:\n\t %q", endpoint, err) + return fmt.Errorf("error calling Get %s:\n\t %q", endpoint, err) } match := false diff --git a/ovh/order_resource_gen.go b/ovh/order_resource_gen.go index c280de786..f709c2e87 100644 --- a/ovh/order_resource_gen.go +++ b/ovh/order_resource_gen.go @@ -332,50 +332,6 @@ func (v *OrderModel) MergeWith(other *OrderModel) { } } -type OrderWritableModel struct { - OvhSubsidiary *ovhtypes.TfStringValue `tfsdk:"ovh_subsidiary" json:"ovhSubsidiary,omitempty"` - Plan *ovhtypes.TfListNestedValue[PlanWritableValue] `tfsdk:"plan" json:"plan,omitempty"` - PlanOption *ovhtypes.TfListNestedValue[PlanOptionWritableValue] `tfsdk:"plan_option" json:"planOption,omitempty"` -} - -func (v OrderModel) ToCreate() *OrderWritableModel { - res := &OrderWritableModel{} - - if !v.OvhSubsidiary.IsUnknown() { - res.OvhSubsidiary = &v.OvhSubsidiary - } - - if !v.Plan.IsUnknown() { - var createPlan []PlanWritableValue - for _, elem := range v.Plan.Elements() { - createPlan = append(createPlan, *elem.(PlanValue).ToCreate()) - } - - newPlan, _ := basetypes.NewListValueFrom(context.Background(), PlanWritableValue{ - PlanValue: &PlanValue{}, - }.Type(context.Background()), createPlan) - res.Plan = &ovhtypes.TfListNestedValue[PlanWritableValue]{ - ListValue: newPlan, - } - } - - if !v.PlanOption.IsUnknown() { - var createPlanOption []PlanOptionWritableValue - for _, elem := range v.PlanOption.Elements() { - createPlanOption = append(createPlanOption, *elem.(PlanOptionValue).ToCreate()) - } - - newPlanOption, _ := basetypes.NewListValueFrom(context.Background(), PlanOptionWritableValue{ - PlanOptionValue: &PlanOptionValue{}, - }.Type(context.Background()), createPlanOption) - res.PlanOption = &ovhtypes.TfListNestedValue[PlanOptionWritableValue]{ - ListValue: newPlanOption, - } - } - - return res -} - var _ basetypes.ObjectTypable = OrderType{} type OrderType struct { @@ -709,36 +665,6 @@ type OrderValue struct { state attr.ValueState } -type OrderWritableValue struct { - *OrderValue `json:"-"` - Date *ovhtypes.TfStringValue `json:"date,omitempty"` - Details *ovhtypes.TfListNestedValue[OrderDetailsValue] `json:"details,omitempty"` - ExpirationDate *ovhtypes.TfStringValue `json:"expirationDate,omitempty"` - OrderId *ovhtypes.TfInt64Value `json:"orderId,omitempty"` -} - -func (v OrderValue) ToCreate() *OrderWritableValue { - res := &OrderWritableValue{} - - if !v.ExpirationDate.IsNull() { - res.ExpirationDate = &v.ExpirationDate - } - - if !v.OrderId.IsNull() { - res.OrderId = &v.OrderId - } - - if !v.Date.IsNull() { - res.Date = &v.Date - } - - if !v.Details.IsNull() { - res.Details = &v.Details - } - - return res -} - func (v *OrderValue) UnmarshalJSON(data []byte) error { type JsonOrderValue OrderValue @@ -1326,41 +1252,6 @@ type OrderDetailsValue struct { state attr.ValueState } -type OrderDetailsWritableValue struct { - *OrderDetailsValue `json:"-"` - Description *ovhtypes.TfStringValue `json:"description,omitempty"` - DetailType *ovhtypes.TfStringValue `json:"detailType,omitempty"` - Domain *ovhtypes.TfStringValue `json:"domain,omitempty"` - OrderDetailId *ovhtypes.TfInt64Value `json:"orderDetailId,omitempty"` - Quantity *ovhtypes.TfStringValue `json:"quantity,omitempty"` -} - -func (v OrderDetailsValue) ToCreate() *OrderDetailsWritableValue { - res := &OrderDetailsWritableValue{} - - if !v.OrderDetailId.IsNull() { - res.OrderDetailId = &v.OrderDetailId - } - - if !v.Quantity.IsNull() { - res.Quantity = &v.Quantity - } - - if !v.Description.IsNull() { - res.Description = &v.Description - } - - if !v.DetailType.IsNull() { - res.DetailType = &v.DetailType - } - - if !v.Domain.IsNull() { - res.Domain = &v.Domain - } - - return res -} - func (v *OrderDetailsValue) UnmarshalJSON(data []byte) error { type JsonOrderDetailsValue OrderDetailsValue @@ -1985,23 +1876,15 @@ type PlanValue struct { PlanCode ovhtypes.TfStringValue `tfsdk:"plan_code" json:"planCode"` PricingMode ovhtypes.TfStringValue `tfsdk:"pricing_mode" json:"pricingMode"` Quantity ovhtypes.TfInt64Value `tfsdk:"quantity" json:"quantity"` + Domain ovhtypes.TfStringValue `tfsdk:"-" json:"domain"` state attr.ValueState } -type PlanWritableValue struct { - *PlanValue `json:"-"` - Configuration *ovhtypes.TfListNestedValue[PlanConfigurationValue] `json:"configuration,omitempty"` - Duration *ovhtypes.TfStringValue `json:"duration,omitempty"` - ItemId *ovhtypes.TfInt64Value `json:"itemId,omitempty"` - PlanCode *ovhtypes.TfStringValue `json:"planCode,omitempty"` - PricingMode *ovhtypes.TfStringValue `json:"pricingMode,omitempty"` - Quantity *ovhtypes.TfInt64Value `json:"quantity,omitempty"` -} - func (opts PlanValue) FromResourceWithPath(d *legacyschema.ResourceData, path string) PlanValue { opts.Duration = ovhtypes.TfStringValue{StringValue: basetypes.NewStringValue(d.Get(fmt.Sprintf("%s.duration", path)).(string))} opts.PlanCode = ovhtypes.TfStringValue{StringValue: basetypes.NewStringValue(d.Get(fmt.Sprintf("%s.plan_code", path)).(string))} opts.PricingMode = ovhtypes.TfStringValue{StringValue: basetypes.NewStringValue(d.Get(fmt.Sprintf("%s.pricing_mode", path)).(string))} + opts.Domain = ovhtypes.NewTfStringValue(d.Get(fmt.Sprintf("%s.domain", path)).(string)) nbConfigs := d.Get(fmt.Sprintf("%s.configuration.#", path)).(int) var configs []attr.Value @@ -2021,36 +1904,6 @@ func (opts PlanValue) FromResourceWithPath(d *legacyschema.ResourceData, path st return opts } -func (v PlanValue) ToCreate() *PlanWritableValue { - res := &PlanWritableValue{} - - if !v.PricingMode.IsNull() { - res.PricingMode = &v.PricingMode - } - - if !v.Quantity.IsNull() { - res.Quantity = &v.Quantity - } - - if !v.Configuration.IsNull() { - res.Configuration = &v.Configuration - } - - if !v.Duration.IsNull() { - res.Duration = &v.Duration - } - - if !v.ItemId.IsNull() { - res.ItemId = &v.ItemId - } - - if !v.PlanCode.IsNull() { - res.PlanCode = &v.PlanCode - } - - return res -} - func (v *PlanValue) UnmarshalJSON(data []byte) error { type JsonPlanValue PlanValue @@ -2115,6 +1968,10 @@ func (v *PlanValue) MergeWith(other *PlanValue) { v.Quantity = other.Quantity } + if (v.Domain.IsUnknown() || v.Domain.IsNull()) && !other.Domain.IsUnknown() { + v.Domain = other.Domain + } + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { v.state = other.state } @@ -2565,26 +2422,6 @@ type PlanConfigurationValue struct { state attr.ValueState } -type PlanConfigurationWritableValue struct { - *PlanConfigurationValue `json:"-"` - Label *ovhtypes.TfStringValue `json:"label,omitempty"` - Value *ovhtypes.TfStringValue `json:"value,omitempty"` -} - -func (v PlanConfigurationValue) ToCreate() *PlanConfigurationWritableValue { - res := &PlanConfigurationWritableValue{} - - if !v.Label.IsNull() { - res.Label = &v.Label - } - - if !v.Value.IsNull() { - res.Value = &v.Value - } - - return res -} - func (v *PlanConfigurationValue) UnmarshalJSON(data []byte) error { type JsonPlanConfigurationValue PlanConfigurationValue @@ -3108,16 +2945,6 @@ type PlanOptionValue struct { state attr.ValueState } -type PlanOptionWritableValue struct { - *PlanOptionValue `json:"-"` - Configuration *ovhtypes.TfListNestedValue[PlanOptionConfigurationValue] `json:"configuration,omitempty"` - Duration *ovhtypes.TfStringValue `json:"duration,omitempty"` - ItemId *ovhtypes.TfInt64Value `json:"itemId,omitempty"` - PlanCode *ovhtypes.TfStringValue `json:"planCode,omitempty"` - PricingMode *ovhtypes.TfStringValue `json:"pricingMode,omitempty"` - Quantity *ovhtypes.TfInt64Value `json:"quantity,omitempty"` -} - func (opts PlanOptionValue) FromResourceWithPath(d *legacyschema.ResourceData, path string) PlanOptionValue { opts.Duration = ovhtypes.TfStringValue{StringValue: basetypes.NewStringValue(d.Get(fmt.Sprintf("%s.duration", path)).(string))} opts.PlanCode = ovhtypes.TfStringValue{StringValue: basetypes.NewStringValue(d.Get(fmt.Sprintf("%s.plan_code", path)).(string))} @@ -3141,36 +2968,6 @@ func (opts PlanOptionValue) FromResourceWithPath(d *legacyschema.ResourceData, p return opts } -func (v PlanOptionValue) ToCreate() *PlanOptionWritableValue { - res := &PlanOptionWritableValue{} - - if !v.Configuration.IsNull() { - res.Configuration = &v.Configuration - } - - if !v.Duration.IsNull() { - res.Duration = &v.Duration - } - - if !v.ItemId.IsNull() { - res.ItemId = &v.ItemId - } - - if !v.PlanCode.IsNull() { - res.PlanCode = &v.PlanCode - } - - if !v.PricingMode.IsNull() { - res.PricingMode = &v.PricingMode - } - - if !v.Quantity.IsNull() { - res.Quantity = &v.Quantity - } - - return res -} - func (v *PlanOptionValue) UnmarshalJSON(data []byte) error { type JsonPlanOptionValue PlanOptionValue diff --git a/ovh/provider_new.go b/ovh/provider_new.go index d926cbf76..c2e238285 100644 --- a/ovh/provider_new.go +++ b/ovh/provider_new.go @@ -226,6 +226,7 @@ func (p *OvhProvider) Resources(_ context.Context) []func() resource.Resource { NewCloudProjectVolumeResource, NewDbaasLogsTokenResource, NewDedicatedServerResource, + NewDomainNameResource, NewDomainZoneDnssecResource, NewDomainZoneImportResource, NewIpFirewallResource, diff --git a/ovh/provider_test.go b/ovh/provider_test.go index 1ec198a65..e7909bcb7 100644 --- a/ovh/provider_test.go +++ b/ovh/provider_test.go @@ -144,7 +144,7 @@ func testAccPreCheckDomain(t *testing.T) { // Checks that the environment variables needed to order /domain for acceptance tests // are set. -func testAccPreCheckOrderDomainZone(t *testing.T) { +func testAccPreCheckOrderDomain(t *testing.T) { testAccPreCheckCredentials(t) checkEnvOrSkip(t, "OVH_TESTACC_ORDER_DOMAIN") } diff --git a/ovh/resource_domain_name.go b/ovh/resource_domain_name.go new file mode 100644 index 000000000..c5dccb280 --- /dev/null +++ b/ovh/resource_domain_name.go @@ -0,0 +1,257 @@ +package ovh + +import ( + "context" + "fmt" + "log" + "net/url" + + "golang.org/x/net/publicsuffix" + + "github.com/ovh/go-ovh/ovh" + "github.com/ovh/terraform-provider-ovh/ovh/types" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +var _ resource.ResourceWithConfigure = (*domainNameResource)(nil) + +func NewDomainNameResource() resource.Resource { + return &domainNameResource{} +} + +type domainNameResource struct { + config *Config +} + +func (r *domainNameResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_domain_name" +} + +func (d *domainNameResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + + config, ok := req.ProviderData.(*Config) + if !ok { + resp.Diagnostics.AddError( + "Unexpected Resource Configure Type", + fmt.Sprintf("Expected *Config, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + return + } + + d.config = config +} + +func (d *domainNameResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = DomainNameResourceSchema(ctx) +} + +func (d *domainNameResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("domain_name"), req.ID)...) +} + +// setDefaultDomainOrderValues fills the plan configuration with a default configuration +// required to order the given domain name +func setDefaultDomainOrderValues(ctx context.Context, order *OrderModel, domain string) { + var plan PlanValue + if len(order.Plan.Elements()) > 0 { + plan = order.Plan.Elements()[0].(PlanValue) + } + + if plan.PricingMode.IsNull() || plan.PricingMode.IsUnknown() { + plan.PricingMode = types.NewTfStringValue("create-default") + } + + if plan.Duration.IsNull() || plan.Duration.IsUnknown() { + plan.Duration = types.NewTfStringValue("P1Y") + } + + if plan.PlanCode.IsNull() || plan.PlanCode.IsUnknown() { + tld, _ := publicsuffix.PublicSuffix(domain) + plan.PlanCode = types.NewTfStringValue(tld) + } + + plan.Domain = types.NewTfStringValue(domain) + + order.Plan = types.TfListNestedValue[PlanValue]{ + ListValue: basetypes.NewListValueMust(plan.Type(ctx), []attr.Value{plan}), + } +} + +func (r *domainNameResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + var data, responseData DomainNameModel + + // Read Terraform plan data into the model + resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + + // Create order and wait for service to be delivered + order := data.ToOrder() + setDefaultDomainOrderValues(ctx, order, data.DomainName.ValueString()) + if err := orderCreate(order, r.config, "domain", true); err != nil { + resp.Diagnostics.AddError("failed to create order", err.Error()) + return + } + + endpoint := "/v2/domain/name/" + url.PathEscape(data.DomainName.ValueString()) + + // Only trigger an update if the target spec is defined + if !data.TargetSpec.IsNull() && !data.TargetSpec.IsUnknown() { + // Read resource to get the checksum required to update it + var initialData DomainNameModel + if err := r.config.OVHClient.Get(endpoint, &initialData); err != nil { + resp.Diagnostics.AddError( + fmt.Sprintf("Error calling Get %s", endpoint), + err.Error(), + ) + return + } + + // Update resource + updateData := data.ToUpdate() + updateData.Checksum = &initialData.Checksum + if err := r.config.OVHClient.Put(endpoint, updateData, nil); err != nil { + resp.Diagnostics.AddError( + fmt.Sprintf("Error calling Put %s", endpoint), + err.Error(), + ) + return + } + } + + // Read updated resource + if err := r.config.OVHClient.Get(endpoint, &responseData); err != nil { + resp.Diagnostics.AddError( + fmt.Sprintf("Error calling Get %s", endpoint), + err.Error(), + ) + return + } + + data.MergeWith(&responseData, true) + + // Save data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +func (r *domainNameResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + var data, responseData DomainNameModel + + // Read Terraform prior state data into the model + resp.Diagnostics.Append(req.State.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + + endpoint := "/v2/domain/name/" + url.PathEscape(data.DomainName.ValueString()) + if err := r.config.OVHClient.Get(endpoint, &responseData); err != nil { + resp.Diagnostics.AddError( + fmt.Sprintf("Error calling Get %s", endpoint), + err.Error(), + ) + return + } + + data.MergeWith(&responseData, true) + + // Save updated data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +func (r *domainNameResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + var data, planData, responseData DomainNameModel + + // Read Terraform plan data into the model + resp.Diagnostics.Append(req.Plan.Get(ctx, &planData)...) + if resp.Diagnostics.HasError() { + return + } + + // Read Terraform prior state data into the model + resp.Diagnostics.Append(req.State.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + + endpoint := "/v2/domain/name/" + url.PathEscape(data.DomainName.ValueString()) + + if !planData.TargetSpec.IsNull() && !planData.TargetSpec.IsUnknown() { + // Set the checksum to its current value + updateData := planData.ToUpdate() + updateData.Checksum = &data.Checksum + + // Update resource + if err := r.config.OVHClient.Put(endpoint, updateData, nil); err != nil { + resp.Diagnostics.AddError( + fmt.Sprintf("Error calling Put %s", endpoint), + err.Error(), + ) + return + } + } + + // Read updated resource + if err := r.config.OVHClient.Get(endpoint, &responseData); err != nil { + resp.Diagnostics.AddError( + fmt.Sprintf("Error calling Get %s", endpoint), + err.Error(), + ) + return + } + + responseData.MergeWith(&planData, false) + + // Save updated data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &responseData)...) +} + +func (r *domainNameResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + var data DomainNameModel + + // Read Terraform prior state data into the model + resp.Diagnostics.Append(req.State.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + + serviceName := data.DomainName.ValueString() + + serviceID, err := serviceIdFromRouteAndResourceName(r.config.OVHClient, "/domain/{serviceName}", serviceName) + if err != nil { + resp.Diagnostics.AddError("failed to retrieve service ID", err.Error()) + } + + terminate := func() (string, error) { + log.Printf("[DEBUG] Will terminate service %s", serviceName) + endpoint := fmt.Sprintf("/services/%d/terminate", serviceID) + if err := r.config.OVHClient.Post(endpoint, nil, nil); err != nil { + if errOvh, ok := err.(*ovh.APIError); ok && (errOvh.Code == 404 || errOvh.Code == 460) { + return "", nil + } + return "", fmt.Errorf("calling Post %s:\n\t %q", endpoint, err) + } + return serviceName, nil + } + + confirmTerminate := func(token string) error { + log.Printf("[DEBUG] Will confirm termination of service %s", serviceName) + endpoint := fmt.Sprintf("/services/%d/terminate/confirm", serviceID) + if err := r.config.OVHClient.Post(endpoint, &ConfirmTerminationOpts{Token: token}, nil); err != nil { + return fmt.Errorf("calling Post %s:\n\t %q", endpoint, err) + } + return nil + } + + if err := orderDelete(r.config, terminate, confirmTerminate); err != nil { + resp.Diagnostics.AddError("failed to delete resource", err.Error()) + return + } +} diff --git a/ovh/resource_domain_name_gen.go b/ovh/resource_domain_name_gen.go new file mode 100644 index 000000000..8df021bc8 --- /dev/null +++ b/ovh/resource_domain_name_gen.go @@ -0,0 +1,4269 @@ +// Code generated by terraform-plugin-framework-generator DO NOT EDIT. + +package ovh + +import ( + "context" + "encoding/json" + "fmt" + "strings" + + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" + + ovhtypes "github.com/ovh/terraform-provider-ovh/ovh/types" +) + +func DomainNameResourceSchema(ctx context.Context) schema.Schema { + attrs := map[string]schema.Attribute{ + "checksum": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Optional: true, + Computed: true, + Description: "Computed hash used to control concurrent modification requests. Here, it represents the current target specification value", + MarkdownDescription: "Computed hash used to control concurrent modification requests. Here, it represents the current target specification value", + }, + "current_state": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "additional_states": schema.ListAttribute{ + CustomType: ovhtypes.NewTfListNestedType[ovhtypes.TfStringValue](ctx), + Computed: true, + Description: "Domain additional states", + MarkdownDescription: "Domain additional states", + }, + "dns_configuration": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "configuration_type": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "The type of DNS configuration of the domain", + MarkdownDescription: "The type of DNS configuration of the domain", + Validators: []validator.String{ + stringvalidator.OneOf( + "ANYCAST", + "DEDICATED", + "EMPTY", + "EXTERNAL", + "HOLD", + "HOSTING", + "MIXED", + "PARKING", + ), + }, + }, + "glue_record_ipv6supported": schema.BoolAttribute{ + CustomType: ovhtypes.TfBoolType{}, + Computed: true, + Description: "Whether the registry supports IPv6 or not", + MarkdownDescription: "Whether the registry supports IPv6 or not", + }, + "host_supported": schema.BoolAttribute{ + CustomType: ovhtypes.TfBoolType{}, + Computed: true, + Description: "Whether the registry accepts hosts or not", + MarkdownDescription: "Whether the registry accepts hosts or not", + }, + "max_dns": schema.Int64Attribute{ + CustomType: ovhtypes.TfInt64Type{}, + Computed: true, + Description: "The maximum number of name servers allowed by the registry", + MarkdownDescription: "The maximum number of name servers allowed by the registry", + }, + "min_dns": schema.Int64Attribute{ + CustomType: ovhtypes.TfInt64Type{}, + Computed: true, + Description: "The minimum number of name servers allowed by the registry", + MarkdownDescription: "The minimum number of name servers allowed by the registry", + }, + "name_servers": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "ipv4": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "The IPv4 associated to the name server", + MarkdownDescription: "The IPv4 associated to the name server", + }, + "ipv6": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "The IPv6 associated to the name server", + MarkdownDescription: "The IPv6 associated to the name server", + }, + "name_server": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "The host name", + MarkdownDescription: "The host name", + }, + "name_server_type": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "The type of name server", + MarkdownDescription: "The type of name server", + Validators: []validator.String{ + stringvalidator.OneOf( + "ANYCAST", + "DEDICATED", + "EMPTY", + "EXTERNAL", + "HOLD", + "HOSTING", + "MIXED", + "PARKING", + ), + }, + }, + }, + CustomType: CurrentStateDnsConfigurationNameServersType{ + ObjectType: types.ObjectType{ + AttrTypes: CurrentStateDnsConfigurationNameServersValue{}.AttributeTypes(ctx), + }, + }, + }, + CustomType: ovhtypes.NewTfListNestedType[CurrentStateDnsConfigurationNameServersValue](ctx), + Computed: true, + Description: "The name servers used by the domain name", + MarkdownDescription: "The name servers used by the domain name", + }, + }, + CustomType: CurrentStateDnsConfigurationType{ + ObjectType: types.ObjectType{ + AttrTypes: CurrentStateDnsConfigurationValue{}.AttributeTypes(ctx), + }, + }, + Computed: true, + Description: "The domain DNS configuration", + MarkdownDescription: "The domain DNS configuration", + }, + "extension": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Extension of the domain name", + MarkdownDescription: "Extension of the domain name", + }, + "main_state": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Domain main state", + MarkdownDescription: "Domain main state", + Validators: []validator.String{ + stringvalidator.OneOf( + "DELETED", + "EXPIRED", + "OK", + "PENDING_CREATE", + "PENDING_DELETE", + "PENDING_INTERNAL_TRANSFER", + "PENDING_OUTGOING_TRANSFER", + "RESTORABLE", + "TO_DELETE", + ), + }, + }, + "name": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Domain name", + MarkdownDescription: "Domain name", + }, + "protection_state": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Domain protection state", + MarkdownDescription: "Domain protection state", + Validators: []validator.String{ + stringvalidator.OneOf( + "PROTECTED", + "UNPROTECTED", + ), + }, + }, + "suspension_state": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Domain suspension state", + MarkdownDescription: "Domain suspension state", + Validators: []validator.String{ + stringvalidator.OneOf( + "NOT_SUSPENDED", + "SUSPENDED", + ), + }, + }, + }, + CustomType: CurrentStateType{ + ObjectType: types.ObjectType{ + AttrTypes: CurrentStateValue{}.AttributeTypes(ctx), + }, + }, + Computed: true, + Description: "Current state of the domain name", + MarkdownDescription: "Current state of the domain name", + }, + "current_tasks": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Identifier of the current task", + MarkdownDescription: "Identifier of the current task", + }, + "link": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Link to the task details", + MarkdownDescription: "Link to the task details", + }, + "status": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Current global status of the current task", + MarkdownDescription: "Current global status of the current task", + Validators: []validator.String{ + stringvalidator.OneOf( + "ERROR", + "PENDING", + "RUNNING", + "SCHEDULED", + ), + }, + }, + "type": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Type of the current task", + MarkdownDescription: "Type of the current task", + }, + }, + CustomType: CurrentTasksType{ + ObjectType: types.ObjectType{ + AttrTypes: CurrentTasksValue{}.AttributeTypes(ctx), + }, + }, + }, + CustomType: ovhtypes.NewTfListNestedType[CurrentTasksValue](ctx), + Computed: true, + Description: "Ongoing asynchronous tasks related to the domain name resource", + MarkdownDescription: "Ongoing asynchronous tasks related to the domain name resource", + }, + "domain_name": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + Description: "Domain name", + MarkdownDescription: "Domain name", + }, + "iam": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "display_name": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Resource display name", + MarkdownDescription: "Resource display name", + }, + "id": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Unique identifier of the resource", + MarkdownDescription: "Unique identifier of the resource", + }, + "tags": schema.MapAttribute{ + CustomType: ovhtypes.NewTfMapNestedType[ovhtypes.TfStringValue](ctx), + Computed: true, + Description: "Resource tags. Tags that were internally computed are prefixed with ovh:", + MarkdownDescription: "Resource tags. Tags that were internally computed are prefixed with ovh:", + }, + "urn": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Unique resource name used in policies", + MarkdownDescription: "Unique resource name used in policies", + }, + }, + CustomType: IamType{ + ObjectType: types.ObjectType{ + AttrTypes: IamValue{}.AttributeTypes(ctx), + }, + }, + Computed: true, + Description: "IAM resource metadata", + MarkdownDescription: "IAM resource metadata", + }, + "id": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Unique identifier for the resource. Here, the domain name itself is used as an identifier", + MarkdownDescription: "Unique identifier for the resource. Here, the domain name itself is used as an identifier", + }, + "resource_status": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Reflects the readiness of the domain name resource. A new target specification request will be accepted only in `READY`, `UPDATING` or `ERROR` status", + MarkdownDescription: "Reflects the readiness of the domain name resource. A new target specification request will be accepted only in `READY`, `UPDATING` or `ERROR` status", + Validators: []validator.String{ + stringvalidator.OneOf( + "CREATING", + "DELETING", + "ERROR", + "READY", + "UPDATING", + ), + }, + }, + "target_spec": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "dns_configuration": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "name_servers": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "ipv4": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Optional: true, + Computed: true, + Description: "The IPv4 associated to the name server", + MarkdownDescription: "The IPv4 associated to the name server", + }, + "ipv6": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Optional: true, + Computed: true, + Description: "The IPv6 associated to the name server", + MarkdownDescription: "The IPv6 associated to the name server", + }, + "name_server": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + // Required: true, + Optional: true, + Computed: true, + Description: "The host name", + MarkdownDescription: "The host name", + }, + }, + CustomType: TargetSpecDnsConfigurationNameServersType{ + ObjectType: types.ObjectType{ + AttrTypes: TargetSpecDnsConfigurationNameServersValue{}.AttributeTypes(ctx), + }, + }, + }, + CustomType: ovhtypes.NewTfListNestedType[TargetSpecDnsConfigurationNameServersValue](ctx), + Optional: true, + Description: "The name servers to update", + MarkdownDescription: "The name servers to update", + }, + }, + CustomType: TargetSpecDnsConfigurationType{ + ObjectType: types.ObjectType{ + AttrTypes: TargetSpecDnsConfigurationValue{}.AttributeTypes(ctx), + }, + }, + Optional: true, + Computed: true, + Description: "The domain DNS configuration", + MarkdownDescription: "The domain DNS configuration", + }, + }, + CustomType: TargetSpecType{ + ObjectType: types.ObjectType{ + AttrTypes: TargetSpecValue{}.AttributeTypes(ctx), + }, + }, + Optional: true, + Computed: true, + Description: "Latest target specification of the domain name resource.", + MarkdownDescription: "Latest target specification of the domain name resource.", + }, + } + for k, v := range OrderResourceSchema(ctx).Attributes { + attrs[k] = v + } + + return schema.Schema{ + Attributes: attrs, + } +} + +type DomainNameModel struct { + Checksum ovhtypes.TfStringValue `tfsdk:"checksum" json:"checksum"` + CurrentState CurrentStateValue `tfsdk:"current_state" json:"currentState"` + CurrentTasks ovhtypes.TfListNestedValue[CurrentTasksValue] `tfsdk:"current_tasks" json:"currentTasks"` + DomainName ovhtypes.TfStringValue `tfsdk:"domain_name" json:"domainName"` + Iam IamValue `tfsdk:"iam" json:"iam"` + Id ovhtypes.TfStringValue `tfsdk:"id" json:"id"` + ResourceStatus ovhtypes.TfStringValue `tfsdk:"resource_status" json:"resourceStatus"` + TargetSpec TargetSpecValue `tfsdk:"target_spec" json:"targetSpec"` + Order OrderValue `tfsdk:"order" json:"order"` + OvhSubsidiary ovhtypes.TfStringValue `tfsdk:"ovh_subsidiary" json:"ovhSubsidiary"` + Plan ovhtypes.TfListNestedValue[PlanValue] `tfsdk:"plan" json:"plan"` + PlanOption ovhtypes.TfListNestedValue[PlanOptionValue] `tfsdk:"plan_option" json:"planOption"` +} + +func (v *DomainNameModel) MergeWith(other *DomainNameModel, overrideChecksum bool) { + if overrideChecksum { + v.Checksum = other.Checksum + } + + if v.CurrentState.IsUnknown() && !other.CurrentState.IsUnknown() { + v.CurrentState = other.CurrentState + } else if !other.CurrentState.IsUnknown() { + v.CurrentState.MergeWith(&other.CurrentState) + } + + if (v.CurrentTasks.IsUnknown() || v.CurrentTasks.IsNull()) && !other.CurrentTasks.IsUnknown() { + v.CurrentTasks = other.CurrentTasks + } else if !other.CurrentTasks.IsUnknown() { + newSlice := make([]attr.Value, 0) + elems := v.CurrentTasks.Elements() + newElems := other.CurrentTasks.Elements() + + if len(elems) != len(newElems) { + v.CurrentTasks = other.CurrentTasks + } else { + for idx, e := range elems { + tmp := e.(CurrentTasksValue) + tmp2 := newElems[idx].(CurrentTasksValue) + tmp.MergeWith(&tmp2) + newSlice = append(newSlice, tmp) + } + + v.CurrentTasks = ovhtypes.TfListNestedValue[CurrentTasksValue]{ + ListValue: basetypes.NewListValueMust(CurrentTasksValue{}.Type(context.Background()), newSlice), + } + } + } + + if (v.DomainName.IsUnknown() || v.DomainName.IsNull()) && !other.DomainName.IsUnknown() { + v.DomainName = other.DomainName + } + + if v.Iam.IsUnknown() && !other.Iam.IsUnknown() { + v.Iam = other.Iam + } else if !other.Iam.IsUnknown() { + v.Iam.MergeWith(&other.Iam) + } + + if (v.Id.IsUnknown() || v.Id.IsNull()) && !other.Id.IsUnknown() { + v.Id = other.Id + } + + if (v.ResourceStatus.IsUnknown() || v.ResourceStatus.IsNull()) && !other.ResourceStatus.IsUnknown() { + v.ResourceStatus = other.ResourceStatus + } + + if v.TargetSpec.IsUnknown() && !other.TargetSpec.IsUnknown() { + v.TargetSpec = other.TargetSpec + } else if !other.TargetSpec.IsUnknown() { + v.TargetSpec.MergeWith(&other.TargetSpec) + } + + if (v.Order.IsUnknown() || v.Order.IsNull()) && !other.Order.IsUnknown() { + v.Order = other.Order + } + + if (v.OvhSubsidiary.IsUnknown() || v.OvhSubsidiary.IsNull()) && !other.OvhSubsidiary.IsUnknown() { + v.OvhSubsidiary = other.OvhSubsidiary + } + + if (v.Plan.IsUnknown() || v.Plan.IsNull()) && !other.Plan.IsUnknown() { + v.Plan = other.Plan + } + + if (v.PlanOption.IsUnknown() || v.PlanOption.IsNull()) && !other.PlanOption.IsUnknown() { + v.PlanOption = other.PlanOption + } + +} + +func (v *DomainNameModel) ToOrder() *OrderModel { + return &OrderModel{ + Order: v.Order, + OvhSubsidiary: v.OvhSubsidiary, + Plan: v.Plan, + PlanOption: v.PlanOption, + } +} + +type DomainNameWritableModel struct { + Checksum *ovhtypes.TfStringValue `tfsdk:"checksum" json:"checksum,omitempty"` + TargetSpec *TargetSpecWritableValue `tfsdk:"target_spec" json:"targetSpec,omitempty"` +} + +func (v DomainNameModel) ToCreate() *DomainNameWritableModel { + res := &DomainNameWritableModel{} + + if !v.Checksum.IsUnknown() { + res.Checksum = &v.Checksum + } + + if !v.TargetSpec.IsUnknown() { + res.TargetSpec = v.TargetSpec.ToCreate() + } + + return res +} + +func (v DomainNameModel) ToUpdate() *DomainNameWritableModel { + res := &DomainNameWritableModel{} + + if !v.Checksum.IsUnknown() { + res.Checksum = &v.Checksum + } + + if !v.TargetSpec.IsUnknown() { + res.TargetSpec = v.TargetSpec.ToUpdate() + } + + return res +} + +var _ basetypes.ObjectTypable = CurrentStateType{} + +type CurrentStateType struct { + basetypes.ObjectType +} + +func (t CurrentStateType) Equal(o attr.Type) bool { + other, ok := o.(CurrentStateType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t CurrentStateType) String() string { + return "CurrentStateType" +} + +func (t CurrentStateType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + additionalStatesAttribute, ok := attributes["additional_states"] + + if !ok { + diags.AddError( + "Attribute Missing", + `additional_states is missing from object`) + + return nil, diags + } + + additionalStatesVal, ok := additionalStatesAttribute.(ovhtypes.TfListNestedValue[ovhtypes.TfStringValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`additional_states expected to be ovhtypes.TfListNestedValue[ovhtypes.TfStringValue], was: %T`, additionalStatesAttribute)) + } + + dnsConfigurationAttribute, ok := attributes["dns_configuration"] + + if !ok { + diags.AddError( + "Attribute Missing", + `dns_configuration is missing from object`) + + return nil, diags + } + + dnsConfigurationVal, ok := dnsConfigurationAttribute.(CurrentStateDnsConfigurationValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`dns_configuration expected to be CurrentStateDnsConfigurationValue, was: %T`, dnsConfigurationAttribute)) + } + + extensionAttribute, ok := attributes["extension"] + + if !ok { + diags.AddError( + "Attribute Missing", + `extension is missing from object`) + + return nil, diags + } + + extensionVal, ok := extensionAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`extension expected to be ovhtypes.TfStringValue, was: %T`, extensionAttribute)) + } + + mainStateAttribute, ok := attributes["main_state"] + + if !ok { + diags.AddError( + "Attribute Missing", + `main_state is missing from object`) + + return nil, diags + } + + mainStateVal, ok := mainStateAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`main_state expected to be ovhtypes.TfStringValue, was: %T`, mainStateAttribute)) + } + + nameAttribute, ok := attributes["name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name is missing from object`) + + return nil, diags + } + + nameVal, ok := nameAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name expected to be ovhtypes.TfStringValue, was: %T`, nameAttribute)) + } + + protectionStateAttribute, ok := attributes["protection_state"] + + if !ok { + diags.AddError( + "Attribute Missing", + `protection_state is missing from object`) + + return nil, diags + } + + protectionStateVal, ok := protectionStateAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`protection_state expected to be ovhtypes.TfStringValue, was: %T`, protectionStateAttribute)) + } + + suspensionStateAttribute, ok := attributes["suspension_state"] + + if !ok { + diags.AddError( + "Attribute Missing", + `suspension_state is missing from object`) + + return nil, diags + } + + suspensionStateVal, ok := suspensionStateAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`suspension_state expected to be ovhtypes.TfStringValue, was: %T`, suspensionStateAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return CurrentStateValue{ + AdditionalStates: additionalStatesVal, + DnsConfiguration: dnsConfigurationVal, + Extension: extensionVal, + MainState: mainStateVal, + Name: nameVal, + ProtectionState: protectionStateVal, + SuspensionState: suspensionStateVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewCurrentStateValueNull() CurrentStateValue { + return CurrentStateValue{ + state: attr.ValueStateNull, + } +} + +func NewCurrentStateValueUnknown() CurrentStateValue { + return CurrentStateValue{ + state: attr.ValueStateUnknown, + } +} + +func NewCurrentStateValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (CurrentStateValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing CurrentStateValue Attribute Value", + "While creating a CurrentStateValue value, a missing attribute value was detected. "+ + "A CurrentStateValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("CurrentStateValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid CurrentStateValue Attribute Type", + "While creating a CurrentStateValue value, an invalid attribute value was detected. "+ + "A CurrentStateValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("CurrentStateValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("CurrentStateValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra CurrentStateValue Attribute Value", + "While creating a CurrentStateValue value, an extra attribute value was detected. "+ + "A CurrentStateValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra CurrentStateValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewCurrentStateValueUnknown(), diags + } + + additionalStatesAttribute, ok := attributes["additional_states"] + + if !ok { + diags.AddError( + "Attribute Missing", + `additional_states is missing from object`) + + return NewCurrentStateValueUnknown(), diags + } + + additionalStatesVal, ok := additionalStatesAttribute.(ovhtypes.TfListNestedValue[ovhtypes.TfStringValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`additional_states expected to be ovhtypes.TfListNestedValue[ovhtypes.TfStringValue], was: %T`, additionalStatesAttribute)) + } + + dnsConfigurationAttribute, ok := attributes["dns_configuration"] + + if !ok { + diags.AddError( + "Attribute Missing", + `dns_configuration is missing from object`) + + return NewCurrentStateValueUnknown(), diags + } + + dnsConfigurationVal, ok := dnsConfigurationAttribute.(CurrentStateDnsConfigurationValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`dns_configuration expected to be CurrentStateDnsConfigurationValue, was: %T`, dnsConfigurationAttribute)) + } + + extensionAttribute, ok := attributes["extension"] + + if !ok { + diags.AddError( + "Attribute Missing", + `extension is missing from object`) + + return NewCurrentStateValueUnknown(), diags + } + + extensionVal, ok := extensionAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`extension expected to be ovhtypes.TfStringValue, was: %T`, extensionAttribute)) + } + + mainStateAttribute, ok := attributes["main_state"] + + if !ok { + diags.AddError( + "Attribute Missing", + `main_state is missing from object`) + + return NewCurrentStateValueUnknown(), diags + } + + mainStateVal, ok := mainStateAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`main_state expected to be ovhtypes.TfStringValue, was: %T`, mainStateAttribute)) + } + + nameAttribute, ok := attributes["name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name is missing from object`) + + return NewCurrentStateValueUnknown(), diags + } + + nameVal, ok := nameAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name expected to be ovhtypes.TfStringValue, was: %T`, nameAttribute)) + } + + protectionStateAttribute, ok := attributes["protection_state"] + + if !ok { + diags.AddError( + "Attribute Missing", + `protection_state is missing from object`) + + return NewCurrentStateValueUnknown(), diags + } + + protectionStateVal, ok := protectionStateAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`protection_state expected to be ovhtypes.TfStringValue, was: %T`, protectionStateAttribute)) + } + + suspensionStateAttribute, ok := attributes["suspension_state"] + + if !ok { + diags.AddError( + "Attribute Missing", + `suspension_state is missing from object`) + + return NewCurrentStateValueUnknown(), diags + } + + suspensionStateVal, ok := suspensionStateAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`suspension_state expected to be ovhtypes.TfStringValue, was: %T`, suspensionStateAttribute)) + } + + if diags.HasError() { + return NewCurrentStateValueUnknown(), diags + } + + return CurrentStateValue{ + AdditionalStates: additionalStatesVal, + DnsConfiguration: dnsConfigurationVal, + Extension: extensionVal, + MainState: mainStateVal, + Name: nameVal, + ProtectionState: protectionStateVal, + SuspensionState: suspensionStateVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewCurrentStateValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) CurrentStateValue { + object, diags := NewCurrentStateValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewCurrentStateValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t CurrentStateType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewCurrentStateValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewCurrentStateValueUnknown(), nil + } + + if in.IsNull() { + return NewCurrentStateValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewCurrentStateValueMust(CurrentStateValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t CurrentStateType) ValueType(ctx context.Context) attr.Value { + return CurrentStateValue{} +} + +var _ basetypes.ObjectValuable = CurrentStateValue{} + +type CurrentStateValue struct { + AdditionalStates ovhtypes.TfListNestedValue[ovhtypes.TfStringValue] `tfsdk:"additional_states" json:"additionalStates"` + DnsConfiguration CurrentStateDnsConfigurationValue `tfsdk:"dns_configuration" json:"dnsConfiguration"` + Extension ovhtypes.TfStringValue `tfsdk:"extension" json:"extension"` + MainState ovhtypes.TfStringValue `tfsdk:"main_state" json:"mainState"` + Name ovhtypes.TfStringValue `tfsdk:"name" json:"name"` + ProtectionState ovhtypes.TfStringValue `tfsdk:"protection_state" json:"protectionState"` + SuspensionState ovhtypes.TfStringValue `tfsdk:"suspension_state" json:"suspensionState"` + state attr.ValueState +} + +func (v *CurrentStateValue) UnmarshalJSON(data []byte) error { + type JsonCurrentStateValue CurrentStateValue + + var tmp JsonCurrentStateValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.AdditionalStates = tmp.AdditionalStates + v.DnsConfiguration = tmp.DnsConfiguration + v.Extension = tmp.Extension + v.MainState = tmp.MainState + v.Name = tmp.Name + v.ProtectionState = tmp.ProtectionState + v.SuspensionState = tmp.SuspensionState + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *CurrentStateValue) MergeWith(other *CurrentStateValue) { + + if (v.AdditionalStates.IsUnknown() || v.AdditionalStates.IsNull()) && !other.AdditionalStates.IsUnknown() { + v.AdditionalStates = other.AdditionalStates + } + + if v.DnsConfiguration.IsUnknown() && !other.DnsConfiguration.IsUnknown() { + v.DnsConfiguration = other.DnsConfiguration + } else if !other.DnsConfiguration.IsUnknown() { + v.DnsConfiguration.MergeWith(&other.DnsConfiguration) + } + + if (v.Extension.IsUnknown() || v.Extension.IsNull()) && !other.Extension.IsUnknown() { + v.Extension = other.Extension + } + + if (v.MainState.IsUnknown() || v.MainState.IsNull()) && !other.MainState.IsUnknown() { + v.MainState = other.MainState + } + + if (v.Name.IsUnknown() || v.Name.IsNull()) && !other.Name.IsUnknown() { + v.Name = other.Name + } + + if (v.ProtectionState.IsUnknown() || v.ProtectionState.IsNull()) && !other.ProtectionState.IsUnknown() { + v.ProtectionState = other.ProtectionState + } + + if (v.SuspensionState.IsUnknown() || v.SuspensionState.IsNull()) && !other.SuspensionState.IsUnknown() { + v.SuspensionState = other.SuspensionState + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v CurrentStateValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "additionalStates": v.AdditionalStates, + "dnsConfiguration": v.DnsConfiguration, + "extension": v.Extension, + "mainState": v.MainState, + "name": v.Name, + "protectionState": v.ProtectionState, + "suspensionState": v.SuspensionState, + } +} +func (v CurrentStateValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 7) + + var val tftypes.Value + var err error + + attrTypes["additional_states"] = basetypes.ListType{ + ElemType: types.StringType, + }.TerraformType(ctx) + attrTypes["dns_configuration"] = basetypes.ObjectType{ + AttrTypes: CurrentStateDnsConfigurationValue{}.AttributeTypes(ctx), + }.TerraformType(ctx) + attrTypes["extension"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["main_state"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["name"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["protection_state"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["suspension_state"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 7) + + val, err = v.AdditionalStates.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["additional_states"] = val + + val, err = v.DnsConfiguration.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["dns_configuration"] = val + + val, err = v.Extension.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["extension"] = val + + val, err = v.MainState.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["main_state"] = val + + val, err = v.Name.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["name"] = val + + val, err = v.ProtectionState.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["protection_state"] = val + + val, err = v.SuspensionState.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["suspension_state"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v CurrentStateValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v CurrentStateValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v CurrentStateValue) String() string { + return "CurrentStateValue" +} + +func (v CurrentStateValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "additional_states": ovhtypes.NewTfListNestedType[ovhtypes.TfStringValue](ctx), + "dns_configuration": CurrentStateDnsConfigurationType{ + basetypes.ObjectType{ + AttrTypes: CurrentStateDnsConfigurationValue{}.AttributeTypes(ctx), + }, + }, + "extension": ovhtypes.TfStringType{}, + "main_state": ovhtypes.TfStringType{}, + "name": ovhtypes.TfStringType{}, + "protection_state": ovhtypes.TfStringType{}, + "suspension_state": ovhtypes.TfStringType{}, + }, + map[string]attr.Value{ + "additional_states": v.AdditionalStates, + "dns_configuration": v.DnsConfiguration, + "extension": v.Extension, + "main_state": v.MainState, + "name": v.Name, + "protection_state": v.ProtectionState, + "suspension_state": v.SuspensionState, + }) + + return objVal, diags +} + +func (v CurrentStateValue) Equal(o attr.Value) bool { + other, ok := o.(CurrentStateValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.AdditionalStates.Equal(other.AdditionalStates) { + return false + } + + if !v.DnsConfiguration.Equal(other.DnsConfiguration) { + return false + } + + if !v.Extension.Equal(other.Extension) { + return false + } + + if !v.MainState.Equal(other.MainState) { + return false + } + + if !v.Name.Equal(other.Name) { + return false + } + + if !v.ProtectionState.Equal(other.ProtectionState) { + return false + } + + if !v.SuspensionState.Equal(other.SuspensionState) { + return false + } + + return true +} + +func (v CurrentStateValue) Type(ctx context.Context) attr.Type { + return CurrentStateType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v CurrentStateValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "additional_states": ovhtypes.NewTfListNestedType[ovhtypes.TfStringValue](ctx), + "dns_configuration": CurrentStateDnsConfigurationValue{}.Type(ctx), + "extension": ovhtypes.TfStringType{}, + "main_state": ovhtypes.TfStringType{}, + "name": ovhtypes.TfStringType{}, + "protection_state": ovhtypes.TfStringType{}, + "suspension_state": ovhtypes.TfStringType{}, + } +} + +var _ basetypes.ObjectTypable = CurrentStateDnsConfigurationType{} + +type CurrentStateDnsConfigurationType struct { + basetypes.ObjectType +} + +func (t CurrentStateDnsConfigurationType) Equal(o attr.Type) bool { + other, ok := o.(CurrentStateDnsConfigurationType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t CurrentStateDnsConfigurationType) String() string { + return "CurrentStateDnsConfigurationType" +} + +func (t CurrentStateDnsConfigurationType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + configurationTypeAttribute, ok := attributes["configuration_type"] + + if !ok { + diags.AddError( + "Attribute Missing", + `configuration_type is missing from object`) + + return nil, diags + } + + configurationTypeVal, ok := configurationTypeAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`configuration_type expected to be ovhtypes.TfStringValue, was: %T`, configurationTypeAttribute)) + } + + glueRecordIpv6supportedAttribute, ok := attributes["glue_record_ipv6supported"] + + if !ok { + diags.AddError( + "Attribute Missing", + `glue_record_ipv6supported is missing from object`) + + return nil, diags + } + + glueRecordIpv6supportedVal, ok := glueRecordIpv6supportedAttribute.(ovhtypes.TfBoolValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`glue_record_ipv6supported expected to be ovhtypes.TfBoolValue, was: %T`, glueRecordIpv6supportedAttribute)) + } + + hostSupportedAttribute, ok := attributes["host_supported"] + + if !ok { + diags.AddError( + "Attribute Missing", + `host_supported is missing from object`) + + return nil, diags + } + + hostSupportedVal, ok := hostSupportedAttribute.(ovhtypes.TfBoolValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`host_supported expected to be ovhtypes.TfBoolValue, was: %T`, hostSupportedAttribute)) + } + + maxDnsAttribute, ok := attributes["max_dns"] + + if !ok { + diags.AddError( + "Attribute Missing", + `max_dns is missing from object`) + + return nil, diags + } + + maxDnsVal, ok := maxDnsAttribute.(ovhtypes.TfInt64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`max_dns expected to be ovhtypes.TfInt64Value, was: %T`, maxDnsAttribute)) + } + + minDnsAttribute, ok := attributes["min_dns"] + + if !ok { + diags.AddError( + "Attribute Missing", + `min_dns is missing from object`) + + return nil, diags + } + + minDnsVal, ok := minDnsAttribute.(ovhtypes.TfInt64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`min_dns expected to be ovhtypes.TfInt64Value, was: %T`, minDnsAttribute)) + } + + nameServersAttribute, ok := attributes["name_servers"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name_servers is missing from object`) + + return nil, diags + } + + nameServersVal, ok := nameServersAttribute.(ovhtypes.TfListNestedValue[CurrentStateDnsConfigurationNameServersValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name_servers expected to be ovhtypes.TfListNestedValue[CurrentStateDnsConfigurationNameServersValue], was: %T`, nameServersAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return CurrentStateDnsConfigurationValue{ + ConfigurationType: configurationTypeVal, + GlueRecordIpv6supported: glueRecordIpv6supportedVal, + HostSupported: hostSupportedVal, + MaxDns: maxDnsVal, + MinDns: minDnsVal, + NameServers: nameServersVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewCurrentStateDnsConfigurationValueNull() CurrentStateDnsConfigurationValue { + return CurrentStateDnsConfigurationValue{ + state: attr.ValueStateNull, + } +} + +func NewCurrentStateDnsConfigurationValueUnknown() CurrentStateDnsConfigurationValue { + return CurrentStateDnsConfigurationValue{ + state: attr.ValueStateUnknown, + } +} + +func NewCurrentStateDnsConfigurationValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (CurrentStateDnsConfigurationValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing CurrentStateDnsConfigurationValue Attribute Value", + "While creating a CurrentStateDnsConfigurationValue value, a missing attribute value was detected. "+ + "A CurrentStateDnsConfigurationValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("CurrentStateDnsConfigurationValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid CurrentStateDnsConfigurationValue Attribute Type", + "While creating a CurrentStateDnsConfigurationValue value, an invalid attribute value was detected. "+ + "A CurrentStateDnsConfigurationValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("CurrentStateDnsConfigurationValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("CurrentStateDnsConfigurationValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra CurrentStateDnsConfigurationValue Attribute Value", + "While creating a CurrentStateDnsConfigurationValue value, an extra attribute value was detected. "+ + "A CurrentStateDnsConfigurationValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra CurrentStateDnsConfigurationValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewCurrentStateDnsConfigurationValueUnknown(), diags + } + + configurationTypeAttribute, ok := attributes["configuration_type"] + + if !ok { + diags.AddError( + "Attribute Missing", + `configuration_type is missing from object`) + + return NewCurrentStateDnsConfigurationValueUnknown(), diags + } + + configurationTypeVal, ok := configurationTypeAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`configuration_type expected to be ovhtypes.TfStringValue, was: %T`, configurationTypeAttribute)) + } + + glueRecordIpv6supportedAttribute, ok := attributes["glue_record_ipv6supported"] + + if !ok { + diags.AddError( + "Attribute Missing", + `glue_record_ipv6supported is missing from object`) + + return NewCurrentStateDnsConfigurationValueUnknown(), diags + } + + glueRecordIpv6supportedVal, ok := glueRecordIpv6supportedAttribute.(ovhtypes.TfBoolValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`glue_record_ipv6supported expected to be ovhtypes.TfBoolValue, was: %T`, glueRecordIpv6supportedAttribute)) + } + + hostSupportedAttribute, ok := attributes["host_supported"] + + if !ok { + diags.AddError( + "Attribute Missing", + `host_supported is missing from object`) + + return NewCurrentStateDnsConfigurationValueUnknown(), diags + } + + hostSupportedVal, ok := hostSupportedAttribute.(ovhtypes.TfBoolValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`host_supported expected to be ovhtypes.TfBoolValue, was: %T`, hostSupportedAttribute)) + } + + maxDnsAttribute, ok := attributes["max_dns"] + + if !ok { + diags.AddError( + "Attribute Missing", + `max_dns is missing from object`) + + return NewCurrentStateDnsConfigurationValueUnknown(), diags + } + + maxDnsVal, ok := maxDnsAttribute.(ovhtypes.TfInt64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`max_dns expected to be ovhtypes.TfInt64Value, was: %T`, maxDnsAttribute)) + } + + minDnsAttribute, ok := attributes["min_dns"] + + if !ok { + diags.AddError( + "Attribute Missing", + `min_dns is missing from object`) + + return NewCurrentStateDnsConfigurationValueUnknown(), diags + } + + minDnsVal, ok := minDnsAttribute.(ovhtypes.TfInt64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`min_dns expected to be ovhtypes.TfInt64Value, was: %T`, minDnsAttribute)) + } + + nameServersAttribute, ok := attributes["name_servers"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name_servers is missing from object`) + + return NewCurrentStateDnsConfigurationValueUnknown(), diags + } + + nameServersVal, ok := nameServersAttribute.(ovhtypes.TfListNestedValue[CurrentStateDnsConfigurationNameServersValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name_servers expected to be ovhtypes.TfListNestedValue[CurrentStateDnsConfigurationNameServersValue], was: %T`, nameServersAttribute)) + } + + if diags.HasError() { + return NewCurrentStateDnsConfigurationValueUnknown(), diags + } + + return CurrentStateDnsConfigurationValue{ + ConfigurationType: configurationTypeVal, + GlueRecordIpv6supported: glueRecordIpv6supportedVal, + HostSupported: hostSupportedVal, + MaxDns: maxDnsVal, + MinDns: minDnsVal, + NameServers: nameServersVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewCurrentStateDnsConfigurationValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) CurrentStateDnsConfigurationValue { + object, diags := NewCurrentStateDnsConfigurationValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewCurrentStateDnsConfigurationValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t CurrentStateDnsConfigurationType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewCurrentStateDnsConfigurationValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewCurrentStateDnsConfigurationValueUnknown(), nil + } + + if in.IsNull() { + return NewCurrentStateDnsConfigurationValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewCurrentStateDnsConfigurationValueMust(CurrentStateDnsConfigurationValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t CurrentStateDnsConfigurationType) ValueType(ctx context.Context) attr.Value { + return CurrentStateDnsConfigurationValue{} +} + +var _ basetypes.ObjectValuable = CurrentStateDnsConfigurationValue{} + +type CurrentStateDnsConfigurationValue struct { + ConfigurationType ovhtypes.TfStringValue `tfsdk:"configuration_type" json:"configurationType"` + GlueRecordIpv6supported ovhtypes.TfBoolValue `tfsdk:"glue_record_ipv6supported" json:"glueRecordIpv6supported"` + HostSupported ovhtypes.TfBoolValue `tfsdk:"host_supported" json:"hostSupported"` + MaxDns ovhtypes.TfInt64Value `tfsdk:"max_dns" json:"maxDns"` + MinDns ovhtypes.TfInt64Value `tfsdk:"min_dns" json:"minDns"` + NameServers ovhtypes.TfListNestedValue[CurrentStateDnsConfigurationNameServersValue] `tfsdk:"name_servers" json:"nameServers"` + state attr.ValueState +} + +type CurrentStateDnsConfigurationWritableValue struct { + *CurrentStateDnsConfigurationValue `json:"-"` + GlueRecordIpv6supported *ovhtypes.TfBoolValue `json:"glueRecordIpv6supported,omitempty"` + HostSupported *ovhtypes.TfBoolValue `json:"hostSupported,omitempty"` +} + +func (v CurrentStateDnsConfigurationValue) ToCreate() *CurrentStateDnsConfigurationWritableValue { + res := &CurrentStateDnsConfigurationWritableValue{} + + if !v.GlueRecordIpv6supported.IsNull() { + res.GlueRecordIpv6supported = &v.GlueRecordIpv6supported + } + + if !v.HostSupported.IsNull() { + res.HostSupported = &v.HostSupported + } + + return res +} + +func (v *CurrentStateDnsConfigurationValue) UnmarshalJSON(data []byte) error { + type JsonCurrentStateDnsConfigurationValue CurrentStateDnsConfigurationValue + + var tmp JsonCurrentStateDnsConfigurationValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.ConfigurationType = tmp.ConfigurationType + v.GlueRecordIpv6supported = tmp.GlueRecordIpv6supported + v.HostSupported = tmp.HostSupported + v.MaxDns = tmp.MaxDns + v.MinDns = tmp.MinDns + v.NameServers = tmp.NameServers + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *CurrentStateDnsConfigurationValue) MergeWith(other *CurrentStateDnsConfigurationValue) { + + if (v.ConfigurationType.IsUnknown() || v.ConfigurationType.IsNull()) && !other.ConfigurationType.IsUnknown() { + v.ConfigurationType = other.ConfigurationType + } + + if (v.GlueRecordIpv6supported.IsUnknown() || v.GlueRecordIpv6supported.IsNull()) && !other.GlueRecordIpv6supported.IsUnknown() { + v.GlueRecordIpv6supported = other.GlueRecordIpv6supported + } + + if (v.HostSupported.IsUnknown() || v.HostSupported.IsNull()) && !other.HostSupported.IsUnknown() { + v.HostSupported = other.HostSupported + } + + if (v.MaxDns.IsUnknown() || v.MaxDns.IsNull()) && !other.MaxDns.IsUnknown() { + v.MaxDns = other.MaxDns + } + + if (v.MinDns.IsUnknown() || v.MinDns.IsNull()) && !other.MinDns.IsUnknown() { + v.MinDns = other.MinDns + } + + if (v.NameServers.IsUnknown() || v.NameServers.IsNull()) && !other.NameServers.IsUnknown() { + v.NameServers = other.NameServers + } else if !other.NameServers.IsUnknown() { + newSlice := make([]attr.Value, 0) + elems := v.NameServers.Elements() + newElems := other.NameServers.Elements() + + if len(elems) != len(newElems) { + v.NameServers = other.NameServers + } else { + for idx, e := range elems { + tmp := e.(CurrentStateDnsConfigurationNameServersValue) + tmp2 := newElems[idx].(CurrentStateDnsConfigurationNameServersValue) + tmp.MergeWith(&tmp2) + newSlice = append(newSlice, tmp) + } + + v.NameServers = ovhtypes.TfListNestedValue[CurrentStateDnsConfigurationNameServersValue]{ + ListValue: basetypes.NewListValueMust(CurrentStateDnsConfigurationNameServersValue{}.Type(context.Background()), newSlice), + } + } + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v CurrentStateDnsConfigurationValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "configurationType": v.ConfigurationType, + "glueRecordIpv6supported": v.GlueRecordIpv6supported, + "hostSupported": v.HostSupported, + "maxDns": v.MaxDns, + "minDns": v.MinDns, + "nameServers": v.NameServers, + } +} +func (v CurrentStateDnsConfigurationValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 6) + + var val tftypes.Value + var err error + + attrTypes["configuration_type"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["glue_record_ipv6supported"] = basetypes.BoolType{}.TerraformType(ctx) + attrTypes["host_supported"] = basetypes.BoolType{}.TerraformType(ctx) + attrTypes["max_dns"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["min_dns"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["name_servers"] = basetypes.ListType{ + ElemType: CurrentStateDnsConfigurationNameServersValue{}.Type(ctx), + }.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 6) + + val, err = v.ConfigurationType.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["configuration_type"] = val + + val, err = v.GlueRecordIpv6supported.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["glue_record_ipv6supported"] = val + + val, err = v.HostSupported.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["host_supported"] = val + + val, err = v.MaxDns.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["max_dns"] = val + + val, err = v.MinDns.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["min_dns"] = val + + val, err = v.NameServers.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["name_servers"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v CurrentStateDnsConfigurationValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v CurrentStateDnsConfigurationValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v CurrentStateDnsConfigurationValue) String() string { + return "CurrentStateDnsConfigurationValue" +} + +func (v CurrentStateDnsConfigurationValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "configuration_type": ovhtypes.TfStringType{}, + "glue_record_ipv6supported": ovhtypes.TfBoolType{}, + "host_supported": ovhtypes.TfBoolType{}, + "max_dns": ovhtypes.TfInt64Type{}, + "min_dns": ovhtypes.TfInt64Type{}, + "name_servers": ovhtypes.NewTfListNestedType[CurrentStateDnsConfigurationNameServersValue](ctx), + }, + map[string]attr.Value{ + "configuration_type": v.ConfigurationType, + "glue_record_ipv6supported": v.GlueRecordIpv6supported, + "host_supported": v.HostSupported, + "max_dns": v.MaxDns, + "min_dns": v.MinDns, + "name_servers": v.NameServers, + }) + + return objVal, diags +} + +func (v CurrentStateDnsConfigurationValue) Equal(o attr.Value) bool { + other, ok := o.(CurrentStateDnsConfigurationValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.ConfigurationType.Equal(other.ConfigurationType) { + return false + } + + if !v.GlueRecordIpv6supported.Equal(other.GlueRecordIpv6supported) { + return false + } + + if !v.HostSupported.Equal(other.HostSupported) { + return false + } + + if !v.MaxDns.Equal(other.MaxDns) { + return false + } + + if !v.MinDns.Equal(other.MinDns) { + return false + } + + if !v.NameServers.Equal(other.NameServers) { + return false + } + + return true +} + +func (v CurrentStateDnsConfigurationValue) Type(ctx context.Context) attr.Type { + return CurrentStateDnsConfigurationType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v CurrentStateDnsConfigurationValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "configuration_type": ovhtypes.TfStringType{}, + "glue_record_ipv6supported": ovhtypes.TfBoolType{}, + "host_supported": ovhtypes.TfBoolType{}, + "max_dns": ovhtypes.TfInt64Type{}, + "min_dns": ovhtypes.TfInt64Type{}, + "name_servers": ovhtypes.NewTfListNestedType[CurrentStateDnsConfigurationNameServersValue](ctx), + } +} + +var _ basetypes.ObjectTypable = CurrentStateDnsConfigurationNameServersType{} + +type CurrentStateDnsConfigurationNameServersType struct { + basetypes.ObjectType +} + +func (t CurrentStateDnsConfigurationNameServersType) Equal(o attr.Type) bool { + other, ok := o.(CurrentStateDnsConfigurationNameServersType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t CurrentStateDnsConfigurationNameServersType) String() string { + return "CurrentStateDnsConfigurationNameServersType" +} + +func (t CurrentStateDnsConfigurationNameServersType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + ipv4Attribute, ok := attributes["ipv4"] + + if !ok { + diags.AddError( + "Attribute Missing", + `ipv4 is missing from object`) + + return nil, diags + } + + ipv4Val, ok := ipv4Attribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`ipv4 expected to be ovhtypes.TfStringValue, was: %T`, ipv4Attribute)) + } + + ipv6Attribute, ok := attributes["ipv6"] + + if !ok { + diags.AddError( + "Attribute Missing", + `ipv6 is missing from object`) + + return nil, diags + } + + ipv6Val, ok := ipv6Attribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`ipv6 expected to be ovhtypes.TfStringValue, was: %T`, ipv6Attribute)) + } + + nameServerAttribute, ok := attributes["name_server"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name_server is missing from object`) + + return nil, diags + } + + nameServerVal, ok := nameServerAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name_server expected to be ovhtypes.TfStringValue, was: %T`, nameServerAttribute)) + } + + nameServerTypeAttribute, ok := attributes["name_server_type"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name_server_type is missing from object`) + + return nil, diags + } + + nameServerTypeVal, ok := nameServerTypeAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name_server_type expected to be ovhtypes.TfStringValue, was: %T`, nameServerTypeAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return CurrentStateDnsConfigurationNameServersValue{ + Ipv4: ipv4Val, + Ipv6: ipv6Val, + NameServer: nameServerVal, + NameServerType: nameServerTypeVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewCurrentStateDnsConfigurationNameServersValueNull() CurrentStateDnsConfigurationNameServersValue { + return CurrentStateDnsConfigurationNameServersValue{ + state: attr.ValueStateNull, + } +} + +func NewCurrentStateDnsConfigurationNameServersValueUnknown() CurrentStateDnsConfigurationNameServersValue { + return CurrentStateDnsConfigurationNameServersValue{ + state: attr.ValueStateUnknown, + } +} + +func NewCurrentStateDnsConfigurationNameServersValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (CurrentStateDnsConfigurationNameServersValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing CurrentStateDnsConfigurationNameServersValue Attribute Value", + "While creating a CurrentStateDnsConfigurationNameServersValue value, a missing attribute value was detected. "+ + "A CurrentStateDnsConfigurationNameServersValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("CurrentStateDnsConfigurationNameServersValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid CurrentStateDnsConfigurationNameServersValue Attribute Type", + "While creating a CurrentStateDnsConfigurationNameServersValue value, an invalid attribute value was detected. "+ + "A CurrentStateDnsConfigurationNameServersValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("CurrentStateDnsConfigurationNameServersValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("CurrentStateDnsConfigurationNameServersValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra CurrentStateDnsConfigurationNameServersValue Attribute Value", + "While creating a CurrentStateDnsConfigurationNameServersValue value, an extra attribute value was detected. "+ + "A CurrentStateDnsConfigurationNameServersValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra CurrentStateDnsConfigurationNameServersValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewCurrentStateDnsConfigurationNameServersValueUnknown(), diags + } + + ipv4Attribute, ok := attributes["ipv4"] + + if !ok { + diags.AddError( + "Attribute Missing", + `ipv4 is missing from object`) + + return NewCurrentStateDnsConfigurationNameServersValueUnknown(), diags + } + + ipv4Val, ok := ipv4Attribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`ipv4 expected to be ovhtypes.TfStringValue, was: %T`, ipv4Attribute)) + } + + ipv6Attribute, ok := attributes["ipv6"] + + if !ok { + diags.AddError( + "Attribute Missing", + `ipv6 is missing from object`) + + return NewCurrentStateDnsConfigurationNameServersValueUnknown(), diags + } + + ipv6Val, ok := ipv6Attribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`ipv6 expected to be ovhtypes.TfStringValue, was: %T`, ipv6Attribute)) + } + + nameServerAttribute, ok := attributes["name_server"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name_server is missing from object`) + + return NewCurrentStateDnsConfigurationNameServersValueUnknown(), diags + } + + nameServerVal, ok := nameServerAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name_server expected to be ovhtypes.TfStringValue, was: %T`, nameServerAttribute)) + } + + nameServerTypeAttribute, ok := attributes["name_server_type"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name_server_type is missing from object`) + + return NewCurrentStateDnsConfigurationNameServersValueUnknown(), diags + } + + nameServerTypeVal, ok := nameServerTypeAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name_server_type expected to be ovhtypes.TfStringValue, was: %T`, nameServerTypeAttribute)) + } + + if diags.HasError() { + return NewCurrentStateDnsConfigurationNameServersValueUnknown(), diags + } + + return CurrentStateDnsConfigurationNameServersValue{ + Ipv4: ipv4Val, + Ipv6: ipv6Val, + NameServer: nameServerVal, + NameServerType: nameServerTypeVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewCurrentStateDnsConfigurationNameServersValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) CurrentStateDnsConfigurationNameServersValue { + object, diags := NewCurrentStateDnsConfigurationNameServersValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewCurrentStateDnsConfigurationNameServersValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t CurrentStateDnsConfigurationNameServersType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewCurrentStateDnsConfigurationNameServersValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewCurrentStateDnsConfigurationNameServersValueUnknown(), nil + } + + if in.IsNull() { + return NewCurrentStateDnsConfigurationNameServersValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewCurrentStateDnsConfigurationNameServersValueMust(CurrentStateDnsConfigurationNameServersValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t CurrentStateDnsConfigurationNameServersType) ValueType(ctx context.Context) attr.Value { + return CurrentStateDnsConfigurationNameServersValue{} +} + +var _ basetypes.ObjectValuable = CurrentStateDnsConfigurationNameServersValue{} + +type CurrentStateDnsConfigurationNameServersValue struct { + Ipv4 ovhtypes.TfStringValue `tfsdk:"ipv4" json:"ipv4"` + Ipv6 ovhtypes.TfStringValue `tfsdk:"ipv6" json:"ipv6"` + NameServer ovhtypes.TfStringValue `tfsdk:"name_server" json:"nameServer"` + NameServerType ovhtypes.TfStringValue `tfsdk:"name_server_type" json:"nameServerType"` + state attr.ValueState +} + +func (v *CurrentStateDnsConfigurationNameServersValue) UnmarshalJSON(data []byte) error { + type JsonCurrentStateDnsConfigurationNameServersValue CurrentStateDnsConfigurationNameServersValue + + var tmp JsonCurrentStateDnsConfigurationNameServersValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.Ipv4 = tmp.Ipv4 + v.Ipv6 = tmp.Ipv6 + v.NameServer = tmp.NameServer + v.NameServerType = tmp.NameServerType + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *CurrentStateDnsConfigurationNameServersValue) MergeWith(other *CurrentStateDnsConfigurationNameServersValue) { + + if (v.Ipv4.IsUnknown() || v.Ipv4.IsNull()) && !other.Ipv4.IsUnknown() { + v.Ipv4 = other.Ipv4 + } + + if (v.Ipv6.IsUnknown() || v.Ipv6.IsNull()) && !other.Ipv6.IsUnknown() { + v.Ipv6 = other.Ipv6 + } + + if (v.NameServer.IsUnknown() || v.NameServer.IsNull()) && !other.NameServer.IsUnknown() { + v.NameServer = other.NameServer + } + + if (v.NameServerType.IsUnknown() || v.NameServerType.IsNull()) && !other.NameServerType.IsUnknown() { + v.NameServerType = other.NameServerType + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v CurrentStateDnsConfigurationNameServersValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "ipv4": v.Ipv4, + "ipv6": v.Ipv6, + "nameServer": v.NameServer, + "nameServerType": v.NameServerType, + } +} +func (v CurrentStateDnsConfigurationNameServersValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 4) + + var val tftypes.Value + var err error + + attrTypes["ipv4"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["ipv6"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["name_server"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["name_server_type"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 4) + + val, err = v.Ipv4.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["ipv4"] = val + + val, err = v.Ipv6.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["ipv6"] = val + + val, err = v.NameServer.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["name_server"] = val + + val, err = v.NameServerType.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["name_server_type"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v CurrentStateDnsConfigurationNameServersValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v CurrentStateDnsConfigurationNameServersValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v CurrentStateDnsConfigurationNameServersValue) String() string { + return "CurrentStateDnsConfigurationNameServersValue" +} + +func (v CurrentStateDnsConfigurationNameServersValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "ipv4": ovhtypes.TfStringType{}, + "ipv6": ovhtypes.TfStringType{}, + "name_server": ovhtypes.TfStringType{}, + "name_server_type": ovhtypes.TfStringType{}, + }, + map[string]attr.Value{ + "ipv4": v.Ipv4, + "ipv6": v.Ipv6, + "name_server": v.NameServer, + "name_server_type": v.NameServerType, + }) + + return objVal, diags +} + +func (v CurrentStateDnsConfigurationNameServersValue) Equal(o attr.Value) bool { + other, ok := o.(CurrentStateDnsConfigurationNameServersValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Ipv4.Equal(other.Ipv4) { + return false + } + + if !v.Ipv6.Equal(other.Ipv6) { + return false + } + + if !v.NameServer.Equal(other.NameServer) { + return false + } + + if !v.NameServerType.Equal(other.NameServerType) { + return false + } + + return true +} + +func (v CurrentStateDnsConfigurationNameServersValue) Type(ctx context.Context) attr.Type { + return CurrentStateDnsConfigurationNameServersType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v CurrentStateDnsConfigurationNameServersValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "ipv4": ovhtypes.TfStringType{}, + "ipv6": ovhtypes.TfStringType{}, + "name_server": ovhtypes.TfStringType{}, + "name_server_type": ovhtypes.TfStringType{}, + } +} + +var _ basetypes.ObjectTypable = CurrentTasksType{} + +type CurrentTasksType struct { + basetypes.ObjectType +} + +func (t CurrentTasksType) Equal(o attr.Type) bool { + other, ok := o.(CurrentTasksType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t CurrentTasksType) String() string { + return "CurrentTasksType" +} + +func (t CurrentTasksType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return nil, diags + } + + idVal, ok := idAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be ovhtypes.TfStringValue, was: %T`, idAttribute)) + } + + linkAttribute, ok := attributes["link"] + + if !ok { + diags.AddError( + "Attribute Missing", + `link is missing from object`) + + return nil, diags + } + + linkVal, ok := linkAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`link expected to be ovhtypes.TfStringValue, was: %T`, linkAttribute)) + } + + statusAttribute, ok := attributes["status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status is missing from object`) + + return nil, diags + } + + statusVal, ok := statusAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status expected to be ovhtypes.TfStringValue, was: %T`, statusAttribute)) + } + + typeAttribute, ok := attributes["type"] + + if !ok { + diags.AddError( + "Attribute Missing", + `type is missing from object`) + + return nil, diags + } + + typeVal, ok := typeAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`type expected to be ovhtypes.TfStringValue, was: %T`, typeAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return CurrentTasksValue{ + Id: idVal, + Link: linkVal, + Status: statusVal, + CurrentTasksType: typeVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewCurrentTasksValueNull() CurrentTasksValue { + return CurrentTasksValue{ + state: attr.ValueStateNull, + } +} + +func NewCurrentTasksValueUnknown() CurrentTasksValue { + return CurrentTasksValue{ + state: attr.ValueStateUnknown, + } +} + +func NewCurrentTasksValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (CurrentTasksValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing CurrentTasksValue Attribute Value", + "While creating a CurrentTasksValue value, a missing attribute value was detected. "+ + "A CurrentTasksValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("CurrentTasksValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid CurrentTasksValue Attribute Type", + "While creating a CurrentTasksValue value, an invalid attribute value was detected. "+ + "A CurrentTasksValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("CurrentTasksValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("CurrentTasksValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra CurrentTasksValue Attribute Value", + "While creating a CurrentTasksValue value, an extra attribute value was detected. "+ + "A CurrentTasksValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra CurrentTasksValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewCurrentTasksValueUnknown(), diags + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return NewCurrentTasksValueUnknown(), diags + } + + idVal, ok := idAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be ovhtypes.TfStringValue, was: %T`, idAttribute)) + } + + linkAttribute, ok := attributes["link"] + + if !ok { + diags.AddError( + "Attribute Missing", + `link is missing from object`) + + return NewCurrentTasksValueUnknown(), diags + } + + linkVal, ok := linkAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`link expected to be ovhtypes.TfStringValue, was: %T`, linkAttribute)) + } + + statusAttribute, ok := attributes["status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status is missing from object`) + + return NewCurrentTasksValueUnknown(), diags + } + + statusVal, ok := statusAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status expected to be ovhtypes.TfStringValue, was: %T`, statusAttribute)) + } + + typeAttribute, ok := attributes["type"] + + if !ok { + diags.AddError( + "Attribute Missing", + `type is missing from object`) + + return NewCurrentTasksValueUnknown(), diags + } + + typeVal, ok := typeAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`type expected to be ovhtypes.TfStringValue, was: %T`, typeAttribute)) + } + + if diags.HasError() { + return NewCurrentTasksValueUnknown(), diags + } + + return CurrentTasksValue{ + Id: idVal, + Link: linkVal, + Status: statusVal, + CurrentTasksType: typeVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewCurrentTasksValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) CurrentTasksValue { + object, diags := NewCurrentTasksValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewCurrentTasksValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t CurrentTasksType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewCurrentTasksValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewCurrentTasksValueUnknown(), nil + } + + if in.IsNull() { + return NewCurrentTasksValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewCurrentTasksValueMust(CurrentTasksValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t CurrentTasksType) ValueType(ctx context.Context) attr.Value { + return CurrentTasksValue{} +} + +var _ basetypes.ObjectValuable = CurrentTasksValue{} + +type CurrentTasksValue struct { + Id ovhtypes.TfStringValue `tfsdk:"id" json:"id"` + Link ovhtypes.TfStringValue `tfsdk:"link" json:"link"` + Status ovhtypes.TfStringValue `tfsdk:"status" json:"status"` + CurrentTasksType ovhtypes.TfStringValue `tfsdk:"type" json:"type"` + state attr.ValueState +} + +func (v *CurrentTasksValue) UnmarshalJSON(data []byte) error { + type JsonCurrentTasksValue CurrentTasksValue + + var tmp JsonCurrentTasksValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.Id = tmp.Id + v.Link = tmp.Link + v.Status = tmp.Status + v.CurrentTasksType = tmp.CurrentTasksType + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *CurrentTasksValue) MergeWith(other *CurrentTasksValue) { + + if (v.Id.IsUnknown() || v.Id.IsNull()) && !other.Id.IsUnknown() { + v.Id = other.Id + } + + if (v.Link.IsUnknown() || v.Link.IsNull()) && !other.Link.IsUnknown() { + v.Link = other.Link + } + + if (v.Status.IsUnknown() || v.Status.IsNull()) && !other.Status.IsUnknown() { + v.Status = other.Status + } + + if (v.CurrentTasksType.IsUnknown() || v.CurrentTasksType.IsNull()) && !other.CurrentTasksType.IsUnknown() { + v.CurrentTasksType = other.CurrentTasksType + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v CurrentTasksValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "id": v.Id, + "link": v.Link, + "status": v.Status, + "type": v.CurrentTasksType, + } +} +func (v CurrentTasksValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 4) + + var val tftypes.Value + var err error + + attrTypes["id"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["link"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["status"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["type"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 4) + + val, err = v.Id.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["id"] = val + + val, err = v.Link.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["link"] = val + + val, err = v.Status.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["status"] = val + + val, err = v.CurrentTasksType.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["type"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v CurrentTasksValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v CurrentTasksValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v CurrentTasksValue) String() string { + return "CurrentTasksValue" +} + +func (v CurrentTasksValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "id": ovhtypes.TfStringType{}, + "link": ovhtypes.TfStringType{}, + "status": ovhtypes.TfStringType{}, + "type": ovhtypes.TfStringType{}, + }, + map[string]attr.Value{ + "id": v.Id, + "link": v.Link, + "status": v.Status, + "type": v.CurrentTasksType, + }) + + return objVal, diags +} + +func (v CurrentTasksValue) Equal(o attr.Value) bool { + other, ok := o.(CurrentTasksValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Id.Equal(other.Id) { + return false + } + + if !v.Link.Equal(other.Link) { + return false + } + + if !v.Status.Equal(other.Status) { + return false + } + + if !v.CurrentTasksType.Equal(other.CurrentTasksType) { + return false + } + + return true +} + +func (v CurrentTasksValue) Type(ctx context.Context) attr.Type { + return CurrentTasksType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v CurrentTasksValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "id": ovhtypes.TfStringType{}, + "link": ovhtypes.TfStringType{}, + "status": ovhtypes.TfStringType{}, + "type": ovhtypes.TfStringType{}, + } +} + +var _ basetypes.ObjectTypable = TargetSpecType{} + +type TargetSpecType struct { + basetypes.ObjectType +} + +func (t TargetSpecType) Equal(o attr.Type) bool { + other, ok := o.(TargetSpecType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t TargetSpecType) String() string { + return "TargetSpecType" +} + +func (t TargetSpecType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + dnsConfigurationAttribute, ok := attributes["dns_configuration"] + + if !ok { + diags.AddError( + "Attribute Missing", + `dns_configuration is missing from object`) + + return nil, diags + } + + dnsConfigurationVal, ok := dnsConfigurationAttribute.(TargetSpecDnsConfigurationValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`dns_configuration expected to be TargetSpecDnsConfigurationValue, was: %T`, dnsConfigurationAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return TargetSpecValue{ + DnsConfiguration: dnsConfigurationVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewTargetSpecValueNull() TargetSpecValue { + return TargetSpecValue{ + state: attr.ValueStateNull, + } +} + +func NewTargetSpecValueUnknown() TargetSpecValue { + return TargetSpecValue{ + state: attr.ValueStateUnknown, + } +} + +func NewTargetSpecValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (TargetSpecValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing TargetSpecValue Attribute Value", + "While creating a TargetSpecValue value, a missing attribute value was detected. "+ + "A TargetSpecValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("TargetSpecValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid TargetSpecValue Attribute Type", + "While creating a TargetSpecValue value, an invalid attribute value was detected. "+ + "A TargetSpecValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("TargetSpecValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("TargetSpecValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra TargetSpecValue Attribute Value", + "While creating a TargetSpecValue value, an extra attribute value was detected. "+ + "A TargetSpecValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra TargetSpecValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewTargetSpecValueUnknown(), diags + } + + dnsConfigurationAttribute, ok := attributes["dns_configuration"] + + if !ok { + diags.AddError( + "Attribute Missing", + `dns_configuration is missing from object`) + + return NewTargetSpecValueUnknown(), diags + } + + dnsConfigurationVal, ok := dnsConfigurationAttribute.(TargetSpecDnsConfigurationValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`dns_configuration expected to be TargetSpecDnsConfigurationValue, was: %T`, dnsConfigurationAttribute)) + } + + if diags.HasError() { + return NewTargetSpecValueUnknown(), diags + } + + return TargetSpecValue{ + DnsConfiguration: dnsConfigurationVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewTargetSpecValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) TargetSpecValue { + object, diags := NewTargetSpecValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewTargetSpecValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t TargetSpecType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewTargetSpecValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewTargetSpecValueUnknown(), nil + } + + if in.IsNull() { + return NewTargetSpecValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewTargetSpecValueMust(TargetSpecValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t TargetSpecType) ValueType(ctx context.Context) attr.Value { + return TargetSpecValue{} +} + +var _ basetypes.ObjectValuable = TargetSpecValue{} + +type TargetSpecValue struct { + DnsConfiguration TargetSpecDnsConfigurationValue `tfsdk:"dns_configuration" json:"dnsConfiguration"` + state attr.ValueState +} + +type TargetSpecWritableValue struct { + *TargetSpecValue `json:"-"` + DnsConfiguration *TargetSpecDnsConfigurationWritableValue `json:"dnsConfiguration,omitempty"` +} + +func (v TargetSpecValue) ToCreate() *TargetSpecWritableValue { + res := &TargetSpecWritableValue{} + + if !v.DnsConfiguration.IsNull() { + res.DnsConfiguration = v.DnsConfiguration.ToCreate() + } + + return res +} + +func (v TargetSpecValue) ToUpdate() *TargetSpecWritableValue { + res := &TargetSpecWritableValue{} + + if !v.DnsConfiguration.IsNull() { + res.DnsConfiguration = v.DnsConfiguration.ToUpdate() + } + + return res +} + +func (v *TargetSpecValue) UnmarshalJSON(data []byte) error { + type JsonTargetSpecValue TargetSpecValue + + var tmp JsonTargetSpecValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.DnsConfiguration = tmp.DnsConfiguration + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *TargetSpecValue) MergeWith(other *TargetSpecValue) { + + if v.DnsConfiguration.IsUnknown() && !other.DnsConfiguration.IsUnknown() { + v.DnsConfiguration = other.DnsConfiguration + } else if !other.DnsConfiguration.IsUnknown() { + v.DnsConfiguration.MergeWith(&other.DnsConfiguration) + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v TargetSpecValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "dnsConfiguration": v.DnsConfiguration, + } +} +func (v TargetSpecValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 1) + + var val tftypes.Value + var err error + + attrTypes["dns_configuration"] = basetypes.ObjectType{ + AttrTypes: TargetSpecDnsConfigurationValue{}.AttributeTypes(ctx), + }.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 1) + + val, err = v.DnsConfiguration.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["dns_configuration"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v TargetSpecValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v TargetSpecValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v TargetSpecValue) String() string { + return "TargetSpecValue" +} + +func (v TargetSpecValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "dns_configuration": TargetSpecDnsConfigurationType{ + basetypes.ObjectType{ + AttrTypes: TargetSpecDnsConfigurationValue{}.AttributeTypes(ctx), + }, + }, + }, + map[string]attr.Value{ + "dns_configuration": v.DnsConfiguration, + }) + + return objVal, diags +} + +func (v TargetSpecValue) Equal(o attr.Value) bool { + other, ok := o.(TargetSpecValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.DnsConfiguration.Equal(other.DnsConfiguration) { + return false + } + + return true +} + +func (v TargetSpecValue) Type(ctx context.Context) attr.Type { + return TargetSpecType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v TargetSpecValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "dns_configuration": TargetSpecDnsConfigurationValue{}.Type(ctx), + } +} + +var _ basetypes.ObjectTypable = TargetSpecDnsConfigurationType{} + +type TargetSpecDnsConfigurationType struct { + basetypes.ObjectType +} + +func (t TargetSpecDnsConfigurationType) Equal(o attr.Type) bool { + other, ok := o.(TargetSpecDnsConfigurationType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t TargetSpecDnsConfigurationType) String() string { + return "TargetSpecDnsConfigurationType" +} + +func (t TargetSpecDnsConfigurationType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + nameServersAttribute, ok := attributes["name_servers"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name_servers is missing from object`) + + return nil, diags + } + + nameServersVal, ok := nameServersAttribute.(ovhtypes.TfListNestedValue[TargetSpecDnsConfigurationNameServersValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name_servers expected to be ovhtypes.TfListNestedValue[TargetSpecDnsConfigurationNameServersValue], was: %T`, nameServersAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return TargetSpecDnsConfigurationValue{ + NameServers: nameServersVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewTargetSpecDnsConfigurationValueNull() TargetSpecDnsConfigurationValue { + return TargetSpecDnsConfigurationValue{ + state: attr.ValueStateNull, + } +} + +func NewTargetSpecDnsConfigurationValueUnknown() TargetSpecDnsConfigurationValue { + return TargetSpecDnsConfigurationValue{ + state: attr.ValueStateUnknown, + } +} + +func NewTargetSpecDnsConfigurationValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (TargetSpecDnsConfigurationValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing TargetSpecDnsConfigurationValue Attribute Value", + "While creating a TargetSpecDnsConfigurationValue value, a missing attribute value was detected. "+ + "A TargetSpecDnsConfigurationValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("TargetSpecDnsConfigurationValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid TargetSpecDnsConfigurationValue Attribute Type", + "While creating a TargetSpecDnsConfigurationValue value, an invalid attribute value was detected. "+ + "A TargetSpecDnsConfigurationValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("TargetSpecDnsConfigurationValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("TargetSpecDnsConfigurationValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra TargetSpecDnsConfigurationValue Attribute Value", + "While creating a TargetSpecDnsConfigurationValue value, an extra attribute value was detected. "+ + "A TargetSpecDnsConfigurationValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra TargetSpecDnsConfigurationValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewTargetSpecDnsConfigurationValueUnknown(), diags + } + + nameServersAttribute, ok := attributes["name_servers"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name_servers is missing from object`) + + return NewTargetSpecDnsConfigurationValueUnknown(), diags + } + + nameServersVal, ok := nameServersAttribute.(ovhtypes.TfListNestedValue[TargetSpecDnsConfigurationNameServersValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name_servers expected to be ovhtypes.TfListNestedValue[TargetSpecDnsConfigurationNameServersValue], was: %T`, nameServersAttribute)) + } + + if diags.HasError() { + return NewTargetSpecDnsConfigurationValueUnknown(), diags + } + + return TargetSpecDnsConfigurationValue{ + NameServers: nameServersVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewTargetSpecDnsConfigurationValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) TargetSpecDnsConfigurationValue { + object, diags := NewTargetSpecDnsConfigurationValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewTargetSpecDnsConfigurationValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t TargetSpecDnsConfigurationType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewTargetSpecDnsConfigurationValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewTargetSpecDnsConfigurationValueUnknown(), nil + } + + if in.IsNull() { + return NewTargetSpecDnsConfigurationValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewTargetSpecDnsConfigurationValueMust(TargetSpecDnsConfigurationValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t TargetSpecDnsConfigurationType) ValueType(ctx context.Context) attr.Value { + return TargetSpecDnsConfigurationValue{} +} + +var _ basetypes.ObjectValuable = TargetSpecDnsConfigurationValue{} + +type TargetSpecDnsConfigurationValue struct { + NameServers ovhtypes.TfListNestedValue[TargetSpecDnsConfigurationNameServersValue] `tfsdk:"name_servers" json:"nameServers"` + state attr.ValueState +} + +type TargetSpecDnsConfigurationWritableValue struct { + *TargetSpecDnsConfigurationValue `json:"-"` + NameServers *ovhtypes.TfListNestedValue[TargetSpecDnsConfigurationNameServersValue] `json:"nameServers,omitempty"` +} + +func (v TargetSpecDnsConfigurationValue) ToCreate() *TargetSpecDnsConfigurationWritableValue { + res := &TargetSpecDnsConfigurationWritableValue{} + + if !v.NameServers.IsNull() { + res.NameServers = &v.NameServers + } + + return res +} + +func (v TargetSpecDnsConfigurationValue) ToUpdate() *TargetSpecDnsConfigurationWritableValue { + res := &TargetSpecDnsConfigurationWritableValue{} + + if !v.NameServers.IsNull() { + res.NameServers = &v.NameServers + } + + return res +} + +func (v *TargetSpecDnsConfigurationValue) UnmarshalJSON(data []byte) error { + type JsonTargetSpecDnsConfigurationValue TargetSpecDnsConfigurationValue + + var tmp JsonTargetSpecDnsConfigurationValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.NameServers = tmp.NameServers + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *TargetSpecDnsConfigurationValue) MergeWith(other *TargetSpecDnsConfigurationValue) { + + if (v.NameServers.IsUnknown() || v.NameServers.IsNull()) && !other.NameServers.IsUnknown() { + v.NameServers = other.NameServers + } else if !other.NameServers.IsUnknown() { + newSlice := make([]attr.Value, 0) + elems := v.NameServers.Elements() + newElems := other.NameServers.Elements() + + if len(elems) != len(newElems) { + v.NameServers = other.NameServers + } else { + for idx, e := range elems { + tmp := e.(TargetSpecDnsConfigurationNameServersValue) + tmp2 := newElems[idx].(TargetSpecDnsConfigurationNameServersValue) + tmp.MergeWith(&tmp2) + newSlice = append(newSlice, tmp) + } + + v.NameServers = ovhtypes.TfListNestedValue[TargetSpecDnsConfigurationNameServersValue]{ + ListValue: basetypes.NewListValueMust(TargetSpecDnsConfigurationNameServersValue{}.Type(context.Background()), newSlice), + } + } + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v TargetSpecDnsConfigurationValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "nameServers": v.NameServers, + } +} +func (v TargetSpecDnsConfigurationValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 1) + + var val tftypes.Value + var err error + + attrTypes["name_servers"] = basetypes.ListType{ + ElemType: TargetSpecDnsConfigurationNameServersValue{}.Type(ctx), + }.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 1) + + val, err = v.NameServers.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["name_servers"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v TargetSpecDnsConfigurationValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v TargetSpecDnsConfigurationValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v TargetSpecDnsConfigurationValue) String() string { + return "TargetSpecDnsConfigurationValue" +} + +func (v TargetSpecDnsConfigurationValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "name_servers": ovhtypes.NewTfListNestedType[TargetSpecDnsConfigurationNameServersValue](ctx), + }, + map[string]attr.Value{ + "name_servers": v.NameServers, + }) + + return objVal, diags +} + +func (v TargetSpecDnsConfigurationValue) Equal(o attr.Value) bool { + other, ok := o.(TargetSpecDnsConfigurationValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.NameServers.Equal(other.NameServers) { + return false + } + + return true +} + +func (v TargetSpecDnsConfigurationValue) Type(ctx context.Context) attr.Type { + return TargetSpecDnsConfigurationType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v TargetSpecDnsConfigurationValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "name_servers": ovhtypes.NewTfListNestedType[TargetSpecDnsConfigurationNameServersValue](ctx), + } +} + +var _ basetypes.ObjectTypable = TargetSpecDnsConfigurationNameServersType{} + +type TargetSpecDnsConfigurationNameServersType struct { + basetypes.ObjectType +} + +func (t TargetSpecDnsConfigurationNameServersType) Equal(o attr.Type) bool { + other, ok := o.(TargetSpecDnsConfigurationNameServersType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t TargetSpecDnsConfigurationNameServersType) String() string { + return "TargetSpecDnsConfigurationNameServersType" +} + +func (t TargetSpecDnsConfigurationNameServersType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + ipv4Attribute, ok := attributes["ipv4"] + + if !ok { + diags.AddError( + "Attribute Missing", + `ipv4 is missing from object`) + + return nil, diags + } + + ipv4Val, ok := ipv4Attribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`ipv4 expected to be ovhtypes.TfStringValue, was: %T`, ipv4Attribute)) + } + + ipv6Attribute, ok := attributes["ipv6"] + + if !ok { + diags.AddError( + "Attribute Missing", + `ipv6 is missing from object`) + + return nil, diags + } + + ipv6Val, ok := ipv6Attribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`ipv6 expected to be ovhtypes.TfStringValue, was: %T`, ipv6Attribute)) + } + + nameServerAttribute, ok := attributes["name_server"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name_server is missing from object`) + + return nil, diags + } + + nameServerVal, ok := nameServerAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name_server expected to be ovhtypes.TfStringValue, was: %T`, nameServerAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return TargetSpecDnsConfigurationNameServersValue{ + Ipv4: ipv4Val, + Ipv6: ipv6Val, + NameServer: nameServerVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewTargetSpecDnsConfigurationNameServersValueNull() TargetSpecDnsConfigurationNameServersValue { + return TargetSpecDnsConfigurationNameServersValue{ + state: attr.ValueStateNull, + } +} + +func NewTargetSpecDnsConfigurationNameServersValueUnknown() TargetSpecDnsConfigurationNameServersValue { + return TargetSpecDnsConfigurationNameServersValue{ + state: attr.ValueStateUnknown, + } +} + +func NewTargetSpecDnsConfigurationNameServersValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (TargetSpecDnsConfigurationNameServersValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing TargetSpecDnsConfigurationNameServersValue Attribute Value", + "While creating a TargetSpecDnsConfigurationNameServersValue value, a missing attribute value was detected. "+ + "A TargetSpecDnsConfigurationNameServersValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("TargetSpecDnsConfigurationNameServersValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid TargetSpecDnsConfigurationNameServersValue Attribute Type", + "While creating a TargetSpecDnsConfigurationNameServersValue value, an invalid attribute value was detected. "+ + "A TargetSpecDnsConfigurationNameServersValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("TargetSpecDnsConfigurationNameServersValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("TargetSpecDnsConfigurationNameServersValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra TargetSpecDnsConfigurationNameServersValue Attribute Value", + "While creating a TargetSpecDnsConfigurationNameServersValue value, an extra attribute value was detected. "+ + "A TargetSpecDnsConfigurationNameServersValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra TargetSpecDnsConfigurationNameServersValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewTargetSpecDnsConfigurationNameServersValueUnknown(), diags + } + + ipv4Attribute, ok := attributes["ipv4"] + + if !ok { + diags.AddError( + "Attribute Missing", + `ipv4 is missing from object`) + + return NewTargetSpecDnsConfigurationNameServersValueUnknown(), diags + } + + ipv4Val, ok := ipv4Attribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`ipv4 expected to be ovhtypes.TfStringValue, was: %T`, ipv4Attribute)) + } + + ipv6Attribute, ok := attributes["ipv6"] + + if !ok { + diags.AddError( + "Attribute Missing", + `ipv6 is missing from object`) + + return NewTargetSpecDnsConfigurationNameServersValueUnknown(), diags + } + + ipv6Val, ok := ipv6Attribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`ipv6 expected to be ovhtypes.TfStringValue, was: %T`, ipv6Attribute)) + } + + nameServerAttribute, ok := attributes["name_server"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name_server is missing from object`) + + return NewTargetSpecDnsConfigurationNameServersValueUnknown(), diags + } + + nameServerVal, ok := nameServerAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name_server expected to be ovhtypes.TfStringValue, was: %T`, nameServerAttribute)) + } + + if diags.HasError() { + return NewTargetSpecDnsConfigurationNameServersValueUnknown(), diags + } + + return TargetSpecDnsConfigurationNameServersValue{ + Ipv4: ipv4Val, + Ipv6: ipv6Val, + NameServer: nameServerVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewTargetSpecDnsConfigurationNameServersValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) TargetSpecDnsConfigurationNameServersValue { + object, diags := NewTargetSpecDnsConfigurationNameServersValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewTargetSpecDnsConfigurationNameServersValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t TargetSpecDnsConfigurationNameServersType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewTargetSpecDnsConfigurationNameServersValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewTargetSpecDnsConfigurationNameServersValueUnknown(), nil + } + + if in.IsNull() { + return NewTargetSpecDnsConfigurationNameServersValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewTargetSpecDnsConfigurationNameServersValueMust(TargetSpecDnsConfigurationNameServersValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t TargetSpecDnsConfigurationNameServersType) ValueType(ctx context.Context) attr.Value { + return TargetSpecDnsConfigurationNameServersValue{} +} + +var _ basetypes.ObjectValuable = TargetSpecDnsConfigurationNameServersValue{} + +type TargetSpecDnsConfigurationNameServersValue struct { + Ipv4 ovhtypes.TfStringValue `tfsdk:"ipv4" json:"ipv4"` + Ipv6 ovhtypes.TfStringValue `tfsdk:"ipv6" json:"ipv6"` + NameServer ovhtypes.TfStringValue `tfsdk:"name_server" json:"nameServer"` + state attr.ValueState +} + +type TargetSpecDnsConfigurationNameServersWritableValue struct { + *TargetSpecDnsConfigurationNameServersValue `json:"-"` + Ipv4 *ovhtypes.TfStringValue `json:"ipv4,omitempty"` + Ipv6 *ovhtypes.TfStringValue `json:"ipv6,omitempty"` + NameServer *ovhtypes.TfStringValue `json:"nameServer,omitempty"` +} + +func (v TargetSpecDnsConfigurationNameServersValue) ToCreate() *TargetSpecDnsConfigurationNameServersWritableValue { + res := &TargetSpecDnsConfigurationNameServersWritableValue{} + + if !v.Ipv4.IsNull() { + res.Ipv4 = &v.Ipv4 + } + + if !v.Ipv6.IsNull() { + res.Ipv6 = &v.Ipv6 + } + + if !v.NameServer.IsNull() { + res.NameServer = &v.NameServer + } + + return res +} + +func (v TargetSpecDnsConfigurationNameServersValue) ToUpdate() *TargetSpecDnsConfigurationNameServersWritableValue { + res := &TargetSpecDnsConfigurationNameServersWritableValue{} + + if !v.Ipv4.IsNull() { + res.Ipv4 = &v.Ipv4 + } + + if !v.Ipv6.IsNull() { + res.Ipv6 = &v.Ipv6 + } + + if !v.NameServer.IsNull() { + res.NameServer = &v.NameServer + } + + return res +} + +func (v *TargetSpecDnsConfigurationNameServersValue) UnmarshalJSON(data []byte) error { + type JsonTargetSpecDnsConfigurationNameServersValue TargetSpecDnsConfigurationNameServersValue + + var tmp JsonTargetSpecDnsConfigurationNameServersValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.Ipv4 = tmp.Ipv4 + v.Ipv6 = tmp.Ipv6 + v.NameServer = tmp.NameServer + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *TargetSpecDnsConfigurationNameServersValue) MergeWith(other *TargetSpecDnsConfigurationNameServersValue) { + + if (v.Ipv4.IsUnknown() || v.Ipv4.IsNull()) && !other.Ipv4.IsUnknown() { + v.Ipv4 = other.Ipv4 + } + + if (v.Ipv6.IsUnknown() || v.Ipv6.IsNull()) && !other.Ipv6.IsUnknown() { + v.Ipv6 = other.Ipv6 + } + + if (v.NameServer.IsUnknown() || v.NameServer.IsNull()) && !other.NameServer.IsUnknown() { + v.NameServer = other.NameServer + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v TargetSpecDnsConfigurationNameServersValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "ipv4": v.Ipv4, + "ipv6": v.Ipv6, + "nameServer": v.NameServer, + } +} +func (v TargetSpecDnsConfigurationNameServersValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 3) + + var val tftypes.Value + var err error + + attrTypes["ipv4"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["ipv6"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["name_server"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 3) + + val, err = v.Ipv4.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["ipv4"] = val + + val, err = v.Ipv6.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["ipv6"] = val + + val, err = v.NameServer.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["name_server"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v TargetSpecDnsConfigurationNameServersValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v TargetSpecDnsConfigurationNameServersValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v TargetSpecDnsConfigurationNameServersValue) String() string { + return "TargetSpecDnsConfigurationNameServersValue" +} + +func (v TargetSpecDnsConfigurationNameServersValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "ipv4": ovhtypes.TfStringType{}, + "ipv6": ovhtypes.TfStringType{}, + "name_server": ovhtypes.TfStringType{}, + }, + map[string]attr.Value{ + "ipv4": v.Ipv4, + "ipv6": v.Ipv6, + "name_server": v.NameServer, + }) + + return objVal, diags +} + +func (v TargetSpecDnsConfigurationNameServersValue) Equal(o attr.Value) bool { + other, ok := o.(TargetSpecDnsConfigurationNameServersValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Ipv4.Equal(other.Ipv4) { + return false + } + + if !v.Ipv6.Equal(other.Ipv6) { + return false + } + + if !v.NameServer.Equal(other.NameServer) { + return false + } + + return true +} + +func (v TargetSpecDnsConfigurationNameServersValue) Type(ctx context.Context) attr.Type { + return TargetSpecDnsConfigurationNameServersType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v TargetSpecDnsConfigurationNameServersValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "ipv4": ovhtypes.TfStringType{}, + "ipv6": ovhtypes.TfStringType{}, + "name_server": ovhtypes.TfStringType{}, + } +} diff --git a/ovh/resource_domain_name_test.go b/ovh/resource_domain_name_test.go new file mode 100644 index 000000000..a85a5e518 --- /dev/null +++ b/ovh/resource_domain_name_test.go @@ -0,0 +1,40 @@ +package ovh + +import ( + "fmt" + "os" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func TestAccResourceDomainName_basic(t *testing.T) { + domain := os.Getenv("OVH_TESTACC_ORDER_DOMAIN") + config := fmt.Sprintf(` + resource "ovh_domain_name" "domain" { + domain_name = "%s" + }`, + domain, + ) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheckOrderDomain(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ovh_domain_name.domain", "id", domain), + resource.TestCheckResourceAttrSet("ovh_domain_name.domain", "checksum"), + resource.TestCheckResourceAttr("ovh_domain_name.domain", "current_state.dns_configuration.name_servers.#", "2"), + ), + }, + { + ResourceName: "ovh_domain_name.name", + ImportState: true, + ImportStateVerify: true, + ImportStateId: domain, + }, + }, + }) +} diff --git a/ovh/resource_domain_zone_test.go b/ovh/resource_domain_zone_test.go index 3ce65bd6d..8595172ea 100644 --- a/ovh/resource_domain_zone_test.go +++ b/ovh/resource_domain_zone_test.go @@ -132,7 +132,7 @@ func TestAccResourceDomainZone_basic(t *testing.T) { t.Logf("[INFO] Will order test zone: %v", name) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheckOrderDomainZone(t) }, + PreCheck: func() { testAccPreCheckOrderDomain(t) }, Providers: testAccProviders, Steps: []resource.TestStep{ { diff --git a/ovh/services.go b/ovh/services.go index 63a2e6b3c..6d37d28f7 100644 --- a/ovh/services.go +++ b/ovh/services.go @@ -48,7 +48,18 @@ type savingsPlanPeriodEndActionRequest struct { func serviceIdFromResourceName(c *ovh.Client, resourceName string) (int, error) { var serviceIds []int - endpoint := fmt.Sprintf("/services?resourceName=%s", url.PathEscape(resourceName)) + endpoint := fmt.Sprintf("/services?resourceName=%s", url.QueryEscape(resourceName)) + + if err := c.Get(endpoint, &serviceIds); err != nil { + return 0, fmt.Errorf("failed to get service infos: %w", err) + } + + return serviceIds[0], nil +} + +func serviceIdFromRouteAndResourceName(c *ovh.Client, route, resourceName string) (int, error) { + var serviceIds []int + endpoint := fmt.Sprintf("/services?resourceName=%s&routes=%s", url.QueryEscape(resourceName), url.QueryEscape(route)) if err := c.Get(endpoint, &serviceIds); err != nil { return 0, fmt.Errorf("failed to get service infos: %w", err) @@ -108,7 +119,7 @@ func serviceUpdateDisplayNameAPIv2(config *Config, serviceName string, displayNa serviceId, err := serviceIdFromResourceName(config.OVHClient, serviceName) if err != nil { diagnostics.AddError( - fmt.Sprintf("Error locating KMS %s", serviceName), + fmt.Sprintf("Error locating service %s", serviceName), err.Error(), ) return err diff --git a/ovh/types_order_cart_generic_product.go b/ovh/types_order_cart_generic_product.go index 2570d47dd..a7ffb4afe 100644 --- a/ovh/types_order_cart_generic_product.go +++ b/ovh/types_order_cart_generic_product.go @@ -1,7 +1,5 @@ package ovh -import () - type OrderCartGenericProduct struct { PlanCode string `json:"planCode"` Prices []OrderCartGenericProductPrice `json:"prices"` diff --git a/vendor/golang.org/x/crypto/ssh/handshake.go b/vendor/golang.org/x/crypto/ssh/handshake.go index 56cdc7c21..fef687db0 100644 --- a/vendor/golang.org/x/crypto/ssh/handshake.go +++ b/vendor/golang.org/x/crypto/ssh/handshake.go @@ -80,6 +80,7 @@ type handshakeTransport struct { pendingPackets [][]byte // Used when a key exchange is in progress. writePacketsLeft uint32 writeBytesLeft int64 + userAuthComplete bool // whether the user authentication phase is complete // If the read loop wants to schedule a kex, it pings this // channel, and the write loop will send out a kex @@ -552,16 +553,25 @@ func (t *handshakeTransport) sendKexInit() error { return nil } +var errSendBannerPhase = errors.New("ssh: SendAuthBanner outside of authentication phase") + func (t *handshakeTransport) writePacket(p []byte) error { + t.mu.Lock() + defer t.mu.Unlock() + switch p[0] { case msgKexInit: return errors.New("ssh: only handshakeTransport can send kexInit") case msgNewKeys: return errors.New("ssh: only handshakeTransport can send newKeys") + case msgUserAuthBanner: + if t.userAuthComplete { + return errSendBannerPhase + } + case msgUserAuthSuccess: + t.userAuthComplete = true } - t.mu.Lock() - defer t.mu.Unlock() if t.writeError != nil { return t.writeError } diff --git a/vendor/golang.org/x/crypto/ssh/server.go b/vendor/golang.org/x/crypto/ssh/server.go index 5b5ccd96f..1839ddc6a 100644 --- a/vendor/golang.org/x/crypto/ssh/server.go +++ b/vendor/golang.org/x/crypto/ssh/server.go @@ -59,6 +59,27 @@ type GSSAPIWithMICConfig struct { Server GSSAPIServer } +// SendAuthBanner implements [ServerPreAuthConn]. +func (s *connection) SendAuthBanner(msg string) error { + return s.transport.writePacket(Marshal(&userAuthBannerMsg{ + Message: msg, + })) +} + +func (*connection) unexportedMethodForFutureProofing() {} + +// ServerPreAuthConn is the interface available on an incoming server +// connection before authentication has completed. +type ServerPreAuthConn interface { + unexportedMethodForFutureProofing() // permits growing ServerPreAuthConn safely later, ala testing.TB + + ConnMetadata + + // SendAuthBanner sends a banner message to the client. + // It returns an error once the authentication phase has ended. + SendAuthBanner(string) error +} + // ServerConfig holds server specific configuration data. type ServerConfig struct { // Config contains configuration shared between client and server. @@ -118,6 +139,12 @@ type ServerConfig struct { // attempts. AuthLogCallback func(conn ConnMetadata, method string, err error) + // PreAuthConnCallback, if non-nil, is called upon receiving a new connection + // before any authentication has started. The provided ServerPreAuthConn + // can be used at any time before authentication is complete, including + // after this callback has returned. + PreAuthConnCallback func(ServerPreAuthConn) + // ServerVersion is the version identification string to announce in // the public handshake. // If empty, a reasonable default is used. @@ -488,6 +515,10 @@ func (b *BannerError) Error() string { } func (s *connection) serverAuthenticate(config *ServerConfig) (*Permissions, error) { + if config.PreAuthConnCallback != nil { + config.PreAuthConnCallback(s) + } + sessionID := s.transport.getSessionID() var cache pubKeyCache var perms *Permissions @@ -495,7 +526,7 @@ func (s *connection) serverAuthenticate(config *ServerConfig) (*Permissions, err authFailures := 0 noneAuthCount := 0 var authErrs []error - var displayedBanner bool + var calledBannerCallback bool partialSuccessReturned := false // Set the initial authentication callbacks from the config. They can be // changed if a PartialSuccessError is returned. @@ -542,14 +573,10 @@ userAuthLoop: s.user = userAuthReq.User - if !displayedBanner && config.BannerCallback != nil { - displayedBanner = true - msg := config.BannerCallback(s) - if msg != "" { - bannerMsg := &userAuthBannerMsg{ - Message: msg, - } - if err := s.transport.writePacket(Marshal(bannerMsg)); err != nil { + if !calledBannerCallback && config.BannerCallback != nil { + calledBannerCallback = true + if msg := config.BannerCallback(s); msg != "" { + if err := s.SendAuthBanner(msg); err != nil { return nil, err } } @@ -762,10 +789,7 @@ userAuthLoop: var bannerErr *BannerError if errors.As(authErr, &bannerErr) { if bannerErr.Message != "" { - bannerMsg := &userAuthBannerMsg{ - Message: bannerErr.Message, - } - if err := s.transport.writePacket(Marshal(bannerMsg)); err != nil { + if err := s.SendAuthBanner(bannerErr.Message); err != nil { return nil, err } } diff --git a/vendor/golang.org/x/net/http2/config.go b/vendor/golang.org/x/net/http2/config.go index de58dfb8d..ca645d9a1 100644 --- a/vendor/golang.org/x/net/http2/config.go +++ b/vendor/golang.org/x/net/http2/config.go @@ -60,7 +60,7 @@ func configFromServer(h1 *http.Server, h2 *Server) http2Config { return conf } -// configFromServer merges configuration settings from h2 and h2.t1.HTTP2 +// configFromTransport merges configuration settings from h2 and h2.t1.HTTP2 // (the net/http Transport). func configFromTransport(h2 *Transport) http2Config { conf := http2Config{ diff --git a/vendor/golang.org/x/net/http2/config_go124.go b/vendor/golang.org/x/net/http2/config_go124.go index e3784123c..5b516c55f 100644 --- a/vendor/golang.org/x/net/http2/config_go124.go +++ b/vendor/golang.org/x/net/http2/config_go124.go @@ -13,7 +13,7 @@ func fillNetHTTPServerConfig(conf *http2Config, srv *http.Server) { fillNetHTTPConfig(conf, srv.HTTP2) } -// fillNetHTTPServerConfig sets fields in conf from tr.HTTP2. +// fillNetHTTPTransportConfig sets fields in conf from tr.HTTP2. func fillNetHTTPTransportConfig(conf *http2Config, tr *http.Transport) { fillNetHTTPConfig(conf, tr.HTTP2) } diff --git a/vendor/golang.org/x/net/http2/http2.go b/vendor/golang.org/x/net/http2/http2.go index c7601c909..6c18ea230 100644 --- a/vendor/golang.org/x/net/http2/http2.go +++ b/vendor/golang.org/x/net/http2/http2.go @@ -34,11 +34,19 @@ import ( ) var ( - VerboseLogs bool - logFrameWrites bool - logFrameReads bool - inTests bool - disableExtendedConnectProtocol bool + VerboseLogs bool + logFrameWrites bool + logFrameReads bool + inTests bool + + // Enabling extended CONNECT by causes browsers to attempt to use + // WebSockets-over-HTTP/2. This results in problems when the server's websocket + // package doesn't support extended CONNECT. + // + // Disable extended CONNECT by default for now. + // + // Issue #71128. + disableExtendedConnectProtocol = true ) func init() { @@ -51,8 +59,8 @@ func init() { logFrameWrites = true logFrameReads = true } - if strings.Contains(e, "http2xconnect=0") { - disableExtendedConnectProtocol = true + if strings.Contains(e, "http2xconnect=1") { + disableExtendedConnectProtocol = false } } @@ -407,23 +415,6 @@ func (s *sorter) SortStrings(ss []string) { s.v = save } -// validPseudoPath reports whether v is a valid :path pseudo-header -// value. It must be either: -// -// - a non-empty string starting with '/' -// - the string '*', for OPTIONS requests. -// -// For now this is only used a quick check for deciding when to clean -// up Opaque URLs before sending requests from the Transport. -// See golang.org/issue/16847 -// -// We used to enforce that the path also didn't start with "//", but -// Google's GFE accepts such paths and Chrome sends them, so ignore -// that part of the spec. See golang.org/issue/19103. -func validPseudoPath(v string) bool { - return (len(v) > 0 && v[0] == '/') || v == "*" -} - // incomparable is a zero-width, non-comparable type. Adding it to a struct // makes that struct also non-comparable, and generally doesn't add // any size (as long as it's first). diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go index b55547aec..7434b8784 100644 --- a/vendor/golang.org/x/net/http2/server.go +++ b/vendor/golang.org/x/net/http2/server.go @@ -50,6 +50,7 @@ import ( "golang.org/x/net/http/httpguts" "golang.org/x/net/http2/hpack" + "golang.org/x/net/internal/httpcommon" ) const ( @@ -812,8 +813,7 @@ const maxCachedCanonicalHeadersKeysSize = 2048 func (sc *serverConn) canonicalHeader(v string) string { sc.serveG.check() - buildCommonHeaderMapsOnce() - cv, ok := commonCanonHeader[v] + cv, ok := httpcommon.CachedCanonicalHeader(v) if ok { return cv } diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go index 090d0e1bd..f2c166b61 100644 --- a/vendor/golang.org/x/net/http2/transport.go +++ b/vendor/golang.org/x/net/http2/transport.go @@ -25,7 +25,6 @@ import ( "net/http" "net/http/httptrace" "net/textproto" - "sort" "strconv" "strings" "sync" @@ -35,6 +34,7 @@ import ( "golang.org/x/net/http/httpguts" "golang.org/x/net/http2/hpack" "golang.org/x/net/idna" + "golang.org/x/net/internal/httpcommon" ) const ( @@ -375,6 +375,7 @@ type ClientConn struct { doNotReuse bool // whether conn is marked to not be reused for any future requests closing bool closed bool + closedOnIdle bool // true if conn was closed for idleness seenSettings bool // true if we've seen a settings frame, false otherwise seenSettingsChan chan struct{} // closed when seenSettings is true or frame reading fails wantSettingsAck bool // we sent a SETTINGS frame and haven't heard back @@ -1089,10 +1090,12 @@ func (cc *ClientConn) idleStateLocked() (st clientConnIdleState) { // If this connection has never been used for a request and is closed, // then let it take a request (which will fail). + // If the conn was closed for idleness, we're racing the idle timer; + // don't try to use the conn. (Issue #70515.) // // This avoids a situation where an error early in a connection's lifetime // goes unreported. - if cc.nextStreamID == 1 && cc.streamsReserved == 0 && cc.closed { + if cc.nextStreamID == 1 && cc.streamsReserved == 0 && cc.closed && !cc.closedOnIdle { st.canTakeNewRequest = true } @@ -1155,6 +1158,7 @@ func (cc *ClientConn) closeIfIdle() { return } cc.closed = true + cc.closedOnIdle = true nextID := cc.nextStreamID // TODO: do clients send GOAWAY too? maybe? Just Close: cc.mu.Unlock() @@ -1271,23 +1275,6 @@ func (cc *ClientConn) closeForLostPing() { // exported. At least they'll be DeepEqual for h1-vs-h2 comparisons tests. var errRequestCanceled = errors.New("net/http: request canceled") -func commaSeparatedTrailers(req *http.Request) (string, error) { - keys := make([]string, 0, len(req.Trailer)) - for k := range req.Trailer { - k = canonicalHeader(k) - switch k { - case "Transfer-Encoding", "Trailer", "Content-Length": - return "", fmt.Errorf("invalid Trailer key %q", k) - } - keys = append(keys, k) - } - if len(keys) > 0 { - sort.Strings(keys) - return strings.Join(keys, ","), nil - } - return "", nil -} - func (cc *ClientConn) responseHeaderTimeout() time.Duration { if cc.t.t1 != nil { return cc.t.t1.ResponseHeaderTimeout @@ -1299,35 +1286,6 @@ func (cc *ClientConn) responseHeaderTimeout() time.Duration { return 0 } -// checkConnHeaders checks whether req has any invalid connection-level headers. -// per RFC 7540 section 8.1.2.2: Connection-Specific Header Fields. -// Certain headers are special-cased as okay but not transmitted later. -func checkConnHeaders(req *http.Request) error { - if v := req.Header.Get("Upgrade"); v != "" { - return fmt.Errorf("http2: invalid Upgrade request header: %q", req.Header["Upgrade"]) - } - if vv := req.Header["Transfer-Encoding"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "chunked") { - return fmt.Errorf("http2: invalid Transfer-Encoding request header: %q", vv) - } - if vv := req.Header["Connection"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && !asciiEqualFold(vv[0], "close") && !asciiEqualFold(vv[0], "keep-alive")) { - return fmt.Errorf("http2: invalid Connection request header: %q", vv) - } - return nil -} - -// actualContentLength returns a sanitized version of -// req.ContentLength, where 0 actually means zero (not unknown) and -1 -// means unknown. -func actualContentLength(req *http.Request) int64 { - if req.Body == nil || req.Body == http.NoBody { - return 0 - } - if req.ContentLength != 0 { - return req.ContentLength - } - return -1 -} - func (cc *ClientConn) decrStreamReservations() { cc.mu.Lock() defer cc.mu.Unlock() @@ -1352,7 +1310,7 @@ func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream)) reqCancel: req.Cancel, isHead: req.Method == "HEAD", reqBody: req.Body, - reqBodyContentLength: actualContentLength(req), + reqBodyContentLength: httpcommon.ActualContentLength(req), trace: httptrace.ContextClientTrace(ctx), peerClosed: make(chan struct{}), abort: make(chan struct{}), @@ -1360,25 +1318,7 @@ func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream)) donec: make(chan struct{}), } - // TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere? - if !cc.t.disableCompression() && - req.Header.Get("Accept-Encoding") == "" && - req.Header.Get("Range") == "" && - !cs.isHead { - // Request gzip only, not deflate. Deflate is ambiguous and - // not as universally supported anyway. - // See: https://zlib.net/zlib_faq.html#faq39 - // - // Note that we don't request this for HEAD requests, - // due to a bug in nginx: - // http://trac.nginx.org/nginx/ticket/358 - // https://golang.org/issue/5522 - // - // We don't request gzip if the request is for a range, since - // auto-decoding a portion of a gzipped document will just fail - // anyway. See https://golang.org/issue/8923 - cs.requestedGzip = true - } + cs.requestedGzip = httpcommon.IsRequestGzip(req, cc.t.disableCompression()) go cs.doRequest(req, streamf) @@ -1409,7 +1349,7 @@ func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream)) } res.Request = req res.TLS = cc.tlsState - if res.Body == noBody && actualContentLength(req) == 0 { + if res.Body == noBody && httpcommon.ActualContentLength(req) == 0 { // If there isn't a request or response body still being // written, then wait for the stream to be closed before // RoundTrip returns. @@ -1492,10 +1432,6 @@ func (cs *clientStream) writeRequest(req *http.Request, streamf func(*clientStre cc := cs.cc ctx := cs.ctx - if err := checkConnHeaders(req); err != nil { - return err - } - // wait for setting frames to be received, a server can change this value later, // but we just wait for the first settings frame var isExtendedConnect bool @@ -1659,20 +1595,22 @@ func (cs *clientStream) encodeAndWriteHeaders(req *http.Request) error { // we send: HEADERS{1}, CONTINUATION{0,} + DATA{0,} (DATA is // sent by writeRequestBody below, along with any Trailers, // again in form HEADERS{1}, CONTINUATION{0,}) - trailers, err := commaSeparatedTrailers(req) - if err != nil { - return err - } - hasTrailers := trailers != "" - contentLen := actualContentLength(req) - hasBody := contentLen != 0 - hdrs, err := cc.encodeHeaders(req, cs.requestedGzip, trailers, contentLen) + cc.hbuf.Reset() + res, err := httpcommon.EncodeHeaders(httpcommon.EncodeHeadersParam{ + Request: req, + AddGzipHeader: cs.requestedGzip, + PeerMaxHeaderListSize: cc.peerMaxHeaderListSize, + DefaultUserAgent: defaultUserAgent, + }, func(name, value string) { + cc.writeHeader(name, value) + }) if err != nil { - return err + return fmt.Errorf("http2: %w", err) } + hdrs := cc.hbuf.Bytes() // Write the request. - endStream := !hasBody && !hasTrailers + endStream := !res.HasBody && !res.HasTrailers cs.sentHeaders = true err = cc.writeHeaders(cs.ID, endStream, int(cc.maxFrameSize), hdrs) traceWroteHeaders(cs.trace) @@ -2066,218 +2004,6 @@ func (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error) } } -func validateHeaders(hdrs http.Header) string { - for k, vv := range hdrs { - if !httpguts.ValidHeaderFieldName(k) && k != ":protocol" { - return fmt.Sprintf("name %q", k) - } - for _, v := range vv { - if !httpguts.ValidHeaderFieldValue(v) { - // Don't include the value in the error, - // because it may be sensitive. - return fmt.Sprintf("value for header %q", k) - } - } - } - return "" -} - -var errNilRequestURL = errors.New("http2: Request.URI is nil") - -func isNormalConnect(req *http.Request) bool { - return req.Method == "CONNECT" && req.Header.Get(":protocol") == "" -} - -// requires cc.wmu be held. -func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trailers string, contentLength int64) ([]byte, error) { - cc.hbuf.Reset() - if req.URL == nil { - return nil, errNilRequestURL - } - - host := req.Host - if host == "" { - host = req.URL.Host - } - host, err := httpguts.PunycodeHostPort(host) - if err != nil { - return nil, err - } - if !httpguts.ValidHostHeader(host) { - return nil, errors.New("http2: invalid Host header") - } - - var path string - if !isNormalConnect(req) { - path = req.URL.RequestURI() - if !validPseudoPath(path) { - orig := path - path = strings.TrimPrefix(path, req.URL.Scheme+"://"+host) - if !validPseudoPath(path) { - if req.URL.Opaque != "" { - return nil, fmt.Errorf("invalid request :path %q from URL.Opaque = %q", orig, req.URL.Opaque) - } else { - return nil, fmt.Errorf("invalid request :path %q", orig) - } - } - } - } - - // Check for any invalid headers+trailers and return an error before we - // potentially pollute our hpack state. (We want to be able to - // continue to reuse the hpack encoder for future requests) - if err := validateHeaders(req.Header); err != "" { - return nil, fmt.Errorf("invalid HTTP header %s", err) - } - if err := validateHeaders(req.Trailer); err != "" { - return nil, fmt.Errorf("invalid HTTP trailer %s", err) - } - - enumerateHeaders := func(f func(name, value string)) { - // 8.1.2.3 Request Pseudo-Header Fields - // The :path pseudo-header field includes the path and query parts of the - // target URI (the path-absolute production and optionally a '?' character - // followed by the query production, see Sections 3.3 and 3.4 of - // [RFC3986]). - f(":authority", host) - m := req.Method - if m == "" { - m = http.MethodGet - } - f(":method", m) - if !isNormalConnect(req) { - f(":path", path) - f(":scheme", req.URL.Scheme) - } - if trailers != "" { - f("trailer", trailers) - } - - var didUA bool - for k, vv := range req.Header { - if asciiEqualFold(k, "host") || asciiEqualFold(k, "content-length") { - // Host is :authority, already sent. - // Content-Length is automatic, set below. - continue - } else if asciiEqualFold(k, "connection") || - asciiEqualFold(k, "proxy-connection") || - asciiEqualFold(k, "transfer-encoding") || - asciiEqualFold(k, "upgrade") || - asciiEqualFold(k, "keep-alive") { - // Per 8.1.2.2 Connection-Specific Header - // Fields, don't send connection-specific - // fields. We have already checked if any - // are error-worthy so just ignore the rest. - continue - } else if asciiEqualFold(k, "user-agent") { - // Match Go's http1 behavior: at most one - // User-Agent. If set to nil or empty string, - // then omit it. Otherwise if not mentioned, - // include the default (below). - didUA = true - if len(vv) < 1 { - continue - } - vv = vv[:1] - if vv[0] == "" { - continue - } - } else if asciiEqualFold(k, "cookie") { - // Per 8.1.2.5 To allow for better compression efficiency, the - // Cookie header field MAY be split into separate header fields, - // each with one or more cookie-pairs. - for _, v := range vv { - for { - p := strings.IndexByte(v, ';') - if p < 0 { - break - } - f("cookie", v[:p]) - p++ - // strip space after semicolon if any. - for p+1 <= len(v) && v[p] == ' ' { - p++ - } - v = v[p:] - } - if len(v) > 0 { - f("cookie", v) - } - } - continue - } - - for _, v := range vv { - f(k, v) - } - } - if shouldSendReqContentLength(req.Method, contentLength) { - f("content-length", strconv.FormatInt(contentLength, 10)) - } - if addGzipHeader { - f("accept-encoding", "gzip") - } - if !didUA { - f("user-agent", defaultUserAgent) - } - } - - // Do a first pass over the headers counting bytes to ensure - // we don't exceed cc.peerMaxHeaderListSize. This is done as a - // separate pass before encoding the headers to prevent - // modifying the hpack state. - hlSize := uint64(0) - enumerateHeaders(func(name, value string) { - hf := hpack.HeaderField{Name: name, Value: value} - hlSize += uint64(hf.Size()) - }) - - if hlSize > cc.peerMaxHeaderListSize { - return nil, errRequestHeaderListSize - } - - trace := httptrace.ContextClientTrace(req.Context()) - traceHeaders := traceHasWroteHeaderField(trace) - - // Header list size is ok. Write the headers. - enumerateHeaders(func(name, value string) { - name, ascii := lowerHeader(name) - if !ascii { - // Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header - // field names have to be ASCII characters (just as in HTTP/1.x). - return - } - cc.writeHeader(name, value) - if traceHeaders { - traceWroteHeaderField(trace, name, value) - } - }) - - return cc.hbuf.Bytes(), nil -} - -// shouldSendReqContentLength reports whether the http2.Transport should send -// a "content-length" request header. This logic is basically a copy of the net/http -// transferWriter.shouldSendContentLength. -// The contentLength is the corrected contentLength (so 0 means actually 0, not unknown). -// -1 means unknown. -func shouldSendReqContentLength(method string, contentLength int64) bool { - if contentLength > 0 { - return true - } - if contentLength < 0 { - return false - } - // For zero bodies, whether we send a content-length depends on the method. - // It also kinda doesn't matter for http2 either way, with END_STREAM. - switch method { - case "POST", "PUT", "PATCH": - return true - default: - return false - } -} - // requires cc.wmu be held. func (cc *ClientConn) encodeTrailers(trailer http.Header) ([]byte, error) { cc.hbuf.Reset() @@ -2294,7 +2020,7 @@ func (cc *ClientConn) encodeTrailers(trailer http.Header) ([]byte, error) { } for k, vv := range trailer { - lowKey, ascii := lowerHeader(k) + lowKey, ascii := httpcommon.LowerHeader(k) if !ascii { // Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header // field names have to be ASCII characters (just as in HTTP/1.x). @@ -2434,9 +2160,12 @@ func (rl *clientConnReadLoop) cleanup() { // This avoids a situation where new connections are constantly created, // added to the pool, fail, and are removed from the pool, without any error // being surfaced to the user. - const unusedWaitTime = 5 * time.Second + unusedWaitTime := 5 * time.Second + if cc.idleTimeout > 0 && unusedWaitTime > cc.idleTimeout { + unusedWaitTime = cc.idleTimeout + } idleTime := cc.t.now().Sub(cc.lastActive) - if atomic.LoadUint32(&cc.atomicReused) == 0 && idleTime < unusedWaitTime { + if atomic.LoadUint32(&cc.atomicReused) == 0 && idleTime < unusedWaitTime && !cc.closedOnIdle { cc.idleTimer = cc.t.afterFunc(unusedWaitTime-idleTime, func() { cc.t.connPool().MarkDead(cc) }) @@ -2646,7 +2375,7 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra Status: status + " " + http.StatusText(statusCode), } for _, hf := range regularFields { - key := canonicalHeader(hf.Name) + key := httpcommon.CanonicalHeader(hf.Name) if key == "Trailer" { t := res.Trailer if t == nil { @@ -2654,7 +2383,7 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra res.Trailer = t } foreachHeaderElement(hf.Value, func(v string) { - t[canonicalHeader(v)] = nil + t[httpcommon.CanonicalHeader(v)] = nil }) } else { vv := header[key] @@ -2778,7 +2507,7 @@ func (rl *clientConnReadLoop) processTrailers(cs *clientStream, f *MetaHeadersFr trailer := make(http.Header) for _, hf := range f.RegularFields() { - key := canonicalHeader(hf.Name) + key := httpcommon.CanonicalHeader(hf.Name) trailer[key] = append(trailer[key], hf.Value) } cs.trailer = trailer @@ -3324,7 +3053,7 @@ func (cc *ClientConn) writeStreamReset(streamID uint32, code ErrCode, ping bool, var ( errResponseHeaderListSize = errors.New("http2: response header list larger than advertised limit") - errRequestHeaderListSize = errors.New("http2: request header list larger than peer's advertised limit") + errRequestHeaderListSize = httpcommon.ErrRequestHeaderListSize ) func (cc *ClientConn) logf(format string, args ...interface{}) { @@ -3508,16 +3237,6 @@ func traceFirstResponseByte(trace *httptrace.ClientTrace) { } } -func traceHasWroteHeaderField(trace *httptrace.ClientTrace) bool { - return trace != nil && trace.WroteHeaderField != nil -} - -func traceWroteHeaderField(trace *httptrace.ClientTrace, k, v string) { - if trace != nil && trace.WroteHeaderField != nil { - trace.WroteHeaderField(k, []string{v}) - } -} - func traceGot1xxResponseFunc(trace *httptrace.ClientTrace) func(int, textproto.MIMEHeader) error { if trace != nil { return trace.Got1xxResponse diff --git a/vendor/golang.org/x/net/http2/write.go b/vendor/golang.org/x/net/http2/write.go index 6ff6bee7e..fdb35b947 100644 --- a/vendor/golang.org/x/net/http2/write.go +++ b/vendor/golang.org/x/net/http2/write.go @@ -13,6 +13,7 @@ import ( "golang.org/x/net/http/httpguts" "golang.org/x/net/http2/hpack" + "golang.org/x/net/internal/httpcommon" ) // writeFramer is implemented by any type that is used to write frames. @@ -351,7 +352,7 @@ func encodeHeaders(enc *hpack.Encoder, h http.Header, keys []string) { } for _, k := range keys { vv := h[k] - k, ascii := lowerHeader(k) + k, ascii := httpcommon.LowerHeader(k) if !ascii { // Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header // field names have to be ASCII characters (just as in HTTP/1.x). diff --git a/vendor/golang.org/x/net/internal/httpcommon/ascii.go b/vendor/golang.org/x/net/internal/httpcommon/ascii.go new file mode 100644 index 000000000..ed14da5af --- /dev/null +++ b/vendor/golang.org/x/net/internal/httpcommon/ascii.go @@ -0,0 +1,53 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package httpcommon + +import "strings" + +// The HTTP protocols are defined in terms of ASCII, not Unicode. This file +// contains helper functions which may use Unicode-aware functions which would +// otherwise be unsafe and could introduce vulnerabilities if used improperly. + +// asciiEqualFold is strings.EqualFold, ASCII only. It reports whether s and t +// are equal, ASCII-case-insensitively. +func asciiEqualFold(s, t string) bool { + if len(s) != len(t) { + return false + } + for i := 0; i < len(s); i++ { + if lower(s[i]) != lower(t[i]) { + return false + } + } + return true +} + +// lower returns the ASCII lowercase version of b. +func lower(b byte) byte { + if 'A' <= b && b <= 'Z' { + return b + ('a' - 'A') + } + return b +} + +// isASCIIPrint returns whether s is ASCII and printable according to +// https://tools.ietf.org/html/rfc20#section-4.2. +func isASCIIPrint(s string) bool { + for i := 0; i < len(s); i++ { + if s[i] < ' ' || s[i] > '~' { + return false + } + } + return true +} + +// asciiToLower returns the lowercase version of s if s is ASCII and printable, +// and whether or not it was. +func asciiToLower(s string) (lower string, ok bool) { + if !isASCIIPrint(s) { + return "", false + } + return strings.ToLower(s), true +} diff --git a/vendor/golang.org/x/net/http2/headermap.go b/vendor/golang.org/x/net/internal/httpcommon/headermap.go similarity index 77% rename from vendor/golang.org/x/net/http2/headermap.go rename to vendor/golang.org/x/net/internal/httpcommon/headermap.go index 149b3dd20..ad3fbacd6 100644 --- a/vendor/golang.org/x/net/http2/headermap.go +++ b/vendor/golang.org/x/net/internal/httpcommon/headermap.go @@ -1,8 +1,8 @@ -// Copyright 2014 The Go Authors. All rights reserved. +// Copyright 2025 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package http2 +package httpcommon import ( "net/http" @@ -88,7 +88,9 @@ func buildCommonHeaderMaps() { } } -func lowerHeader(v string) (lower string, ascii bool) { +// LowerHeader returns the lowercase form of a header name, +// used on the wire for HTTP/2 and HTTP/3 requests. +func LowerHeader(v string) (lower string, ascii bool) { buildCommonHeaderMapsOnce() if s, ok := commonLowerHeader[v]; ok { return s, true @@ -96,10 +98,18 @@ func lowerHeader(v string) (lower string, ascii bool) { return asciiToLower(v) } -func canonicalHeader(v string) string { +// CanonicalHeader canonicalizes a header name. (For example, "host" becomes "Host".) +func CanonicalHeader(v string) string { buildCommonHeaderMapsOnce() if s, ok := commonCanonHeader[v]; ok { return s } return http.CanonicalHeaderKey(v) } + +// CachedCanonicalHeader returns the canonical form of a well-known header name. +func CachedCanonicalHeader(v string) (string, bool) { + buildCommonHeaderMapsOnce() + s, ok := commonCanonHeader[v] + return s, ok +} diff --git a/vendor/golang.org/x/net/internal/httpcommon/request.go b/vendor/golang.org/x/net/internal/httpcommon/request.go new file mode 100644 index 000000000..343914773 --- /dev/null +++ b/vendor/golang.org/x/net/internal/httpcommon/request.go @@ -0,0 +1,379 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package httpcommon + +import ( + "errors" + "fmt" + "net/http" + "net/http/httptrace" + "sort" + "strconv" + "strings" + + "golang.org/x/net/http/httpguts" + "golang.org/x/net/http2/hpack" +) + +var ( + ErrRequestHeaderListSize = errors.New("request header list larger than peer's advertised limit") +) + +// EncodeHeadersParam is parameters to EncodeHeaders. +type EncodeHeadersParam struct { + Request *http.Request + + // AddGzipHeader indicates that an "accept-encoding: gzip" header should be + // added to the request. + AddGzipHeader bool + + // PeerMaxHeaderListSize, when non-zero, is the peer's MAX_HEADER_LIST_SIZE setting. + PeerMaxHeaderListSize uint64 + + // DefaultUserAgent is the User-Agent header to send when the request + // neither contains a User-Agent nor disables it. + DefaultUserAgent string +} + +// EncodeHeadersParam is the result of EncodeHeaders. +type EncodeHeadersResult struct { + HasBody bool + HasTrailers bool +} + +// EncodeHeaders constructs request headers common to HTTP/2 and HTTP/3. +// It validates a request and calls headerf with each pseudo-header and header +// for the request. +// The headerf function is called with the validated, canonicalized header name. +func EncodeHeaders(param EncodeHeadersParam, headerf func(name, value string)) (res EncodeHeadersResult, _ error) { + req := param.Request + + // Check for invalid connection-level headers. + if err := checkConnHeaders(req); err != nil { + return res, err + } + + if req.URL == nil { + return res, errors.New("Request.URL is nil") + } + + host := req.Host + if host == "" { + host = req.URL.Host + } + host, err := httpguts.PunycodeHostPort(host) + if err != nil { + return res, err + } + if !httpguts.ValidHostHeader(host) { + return res, errors.New("invalid Host header") + } + + // isNormalConnect is true if this is a non-extended CONNECT request. + isNormalConnect := false + protocol := req.Header.Get(":protocol") + if req.Method == "CONNECT" && protocol == "" { + isNormalConnect = true + } else if protocol != "" && req.Method != "CONNECT" { + return res, errors.New("invalid :protocol header in non-CONNECT request") + } + + // Validate the path, except for non-extended CONNECT requests which have no path. + var path string + if !isNormalConnect { + path = req.URL.RequestURI() + if !validPseudoPath(path) { + orig := path + path = strings.TrimPrefix(path, req.URL.Scheme+"://"+host) + if !validPseudoPath(path) { + if req.URL.Opaque != "" { + return res, fmt.Errorf("invalid request :path %q from URL.Opaque = %q", orig, req.URL.Opaque) + } else { + return res, fmt.Errorf("invalid request :path %q", orig) + } + } + } + } + + // Check for any invalid headers+trailers and return an error before we + // potentially pollute our hpack state. (We want to be able to + // continue to reuse the hpack encoder for future requests) + if err := validateHeaders(req.Header); err != "" { + return res, fmt.Errorf("invalid HTTP header %s", err) + } + if err := validateHeaders(req.Trailer); err != "" { + return res, fmt.Errorf("invalid HTTP trailer %s", err) + } + + contentLength := ActualContentLength(req) + + trailers, err := commaSeparatedTrailers(req) + if err != nil { + return res, err + } + + enumerateHeaders := func(f func(name, value string)) { + // 8.1.2.3 Request Pseudo-Header Fields + // The :path pseudo-header field includes the path and query parts of the + // target URI (the path-absolute production and optionally a '?' character + // followed by the query production, see Sections 3.3 and 3.4 of + // [RFC3986]). + f(":authority", host) + m := req.Method + if m == "" { + m = http.MethodGet + } + f(":method", m) + if !isNormalConnect { + f(":path", path) + f(":scheme", req.URL.Scheme) + } + if protocol != "" { + f(":protocol", protocol) + } + if trailers != "" { + f("trailer", trailers) + } + + var didUA bool + for k, vv := range req.Header { + if asciiEqualFold(k, "host") || asciiEqualFold(k, "content-length") { + // Host is :authority, already sent. + // Content-Length is automatic, set below. + continue + } else if asciiEqualFold(k, "connection") || + asciiEqualFold(k, "proxy-connection") || + asciiEqualFold(k, "transfer-encoding") || + asciiEqualFold(k, "upgrade") || + asciiEqualFold(k, "keep-alive") { + // Per 8.1.2.2 Connection-Specific Header + // Fields, don't send connection-specific + // fields. We have already checked if any + // are error-worthy so just ignore the rest. + continue + } else if asciiEqualFold(k, "user-agent") { + // Match Go's http1 behavior: at most one + // User-Agent. If set to nil or empty string, + // then omit it. Otherwise if not mentioned, + // include the default (below). + didUA = true + if len(vv) < 1 { + continue + } + vv = vv[:1] + if vv[0] == "" { + continue + } + } else if asciiEqualFold(k, "cookie") { + // Per 8.1.2.5 To allow for better compression efficiency, the + // Cookie header field MAY be split into separate header fields, + // each with one or more cookie-pairs. + for _, v := range vv { + for { + p := strings.IndexByte(v, ';') + if p < 0 { + break + } + f("cookie", v[:p]) + p++ + // strip space after semicolon if any. + for p+1 <= len(v) && v[p] == ' ' { + p++ + } + v = v[p:] + } + if len(v) > 0 { + f("cookie", v) + } + } + continue + } else if k == ":protocol" { + // :protocol pseudo-header was already sent above. + continue + } + + for _, v := range vv { + f(k, v) + } + } + if shouldSendReqContentLength(req.Method, contentLength) { + f("content-length", strconv.FormatInt(contentLength, 10)) + } + if param.AddGzipHeader { + f("accept-encoding", "gzip") + } + if !didUA { + f("user-agent", param.DefaultUserAgent) + } + } + + // Do a first pass over the headers counting bytes to ensure + // we don't exceed cc.peerMaxHeaderListSize. This is done as a + // separate pass before encoding the headers to prevent + // modifying the hpack state. + if param.PeerMaxHeaderListSize > 0 { + hlSize := uint64(0) + enumerateHeaders(func(name, value string) { + hf := hpack.HeaderField{Name: name, Value: value} + hlSize += uint64(hf.Size()) + }) + + if hlSize > param.PeerMaxHeaderListSize { + return res, ErrRequestHeaderListSize + } + } + + trace := httptrace.ContextClientTrace(req.Context()) + + // Header list size is ok. Write the headers. + enumerateHeaders(func(name, value string) { + name, ascii := LowerHeader(name) + if !ascii { + // Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header + // field names have to be ASCII characters (just as in HTTP/1.x). + return + } + + headerf(name, value) + + if trace != nil && trace.WroteHeaderField != nil { + trace.WroteHeaderField(name, []string{value}) + } + }) + + res.HasBody = contentLength != 0 + res.HasTrailers = trailers != "" + return res, nil +} + +// IsRequestGzip reports whether we should add an Accept-Encoding: gzip header +// for a request. +func IsRequestGzip(req *http.Request, disableCompression bool) bool { + // TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere? + if !disableCompression && + req.Header.Get("Accept-Encoding") == "" && + req.Header.Get("Range") == "" && + req.Method != "HEAD" { + // Request gzip only, not deflate. Deflate is ambiguous and + // not as universally supported anyway. + // See: https://zlib.net/zlib_faq.html#faq39 + // + // Note that we don't request this for HEAD requests, + // due to a bug in nginx: + // http://trac.nginx.org/nginx/ticket/358 + // https://golang.org/issue/5522 + // + // We don't request gzip if the request is for a range, since + // auto-decoding a portion of a gzipped document will just fail + // anyway. See https://golang.org/issue/8923 + return true + } + return false +} + +// checkConnHeaders checks whether req has any invalid connection-level headers. +// +// https://www.rfc-editor.org/rfc/rfc9114.html#section-4.2-3 +// https://www.rfc-editor.org/rfc/rfc9113.html#section-8.2.2-1 +// +// Certain headers are special-cased as okay but not transmitted later. +// For example, we allow "Transfer-Encoding: chunked", but drop the header when encoding. +func checkConnHeaders(req *http.Request) error { + if v := req.Header.Get("Upgrade"); v != "" { + return fmt.Errorf("invalid Upgrade request header: %q", req.Header["Upgrade"]) + } + if vv := req.Header["Transfer-Encoding"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "chunked") { + return fmt.Errorf("invalid Transfer-Encoding request header: %q", vv) + } + if vv := req.Header["Connection"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && !asciiEqualFold(vv[0], "close") && !asciiEqualFold(vv[0], "keep-alive")) { + return fmt.Errorf("invalid Connection request header: %q", vv) + } + return nil +} + +func commaSeparatedTrailers(req *http.Request) (string, error) { + keys := make([]string, 0, len(req.Trailer)) + for k := range req.Trailer { + k = CanonicalHeader(k) + switch k { + case "Transfer-Encoding", "Trailer", "Content-Length": + return "", fmt.Errorf("invalid Trailer key %q", k) + } + keys = append(keys, k) + } + if len(keys) > 0 { + sort.Strings(keys) + return strings.Join(keys, ","), nil + } + return "", nil +} + +// ActualContentLength returns a sanitized version of +// req.ContentLength, where 0 actually means zero (not unknown) and -1 +// means unknown. +func ActualContentLength(req *http.Request) int64 { + if req.Body == nil || req.Body == http.NoBody { + return 0 + } + if req.ContentLength != 0 { + return req.ContentLength + } + return -1 +} + +// validPseudoPath reports whether v is a valid :path pseudo-header +// value. It must be either: +// +// - a non-empty string starting with '/' +// - the string '*', for OPTIONS requests. +// +// For now this is only used a quick check for deciding when to clean +// up Opaque URLs before sending requests from the Transport. +// See golang.org/issue/16847 +// +// We used to enforce that the path also didn't start with "//", but +// Google's GFE accepts such paths and Chrome sends them, so ignore +// that part of the spec. See golang.org/issue/19103. +func validPseudoPath(v string) bool { + return (len(v) > 0 && v[0] == '/') || v == "*" +} + +func validateHeaders(hdrs http.Header) string { + for k, vv := range hdrs { + if !httpguts.ValidHeaderFieldName(k) && k != ":protocol" { + return fmt.Sprintf("name %q", k) + } + for _, v := range vv { + if !httpguts.ValidHeaderFieldValue(v) { + // Don't include the value in the error, + // because it may be sensitive. + return fmt.Sprintf("value for header %q", k) + } + } + } + return "" +} + +// shouldSendReqContentLength reports whether we should send +// a "content-length" request header. This logic is basically a copy of the net/http +// transferWriter.shouldSendContentLength. +// The contentLength is the corrected contentLength (so 0 means actually 0, not unknown). +// -1 means unknown. +func shouldSendReqContentLength(method string, contentLength int64) bool { + if contentLength > 0 { + return true + } + if contentLength < 0 { + return false + } + // For zero bodies, whether we send a content-length depends on the method. + // It also kinda doesn't matter for http2 either way, with END_STREAM. + switch method { + case "POST", "PUT", "PATCH": + return true + default: + return false + } +} diff --git a/vendor/golang.org/x/net/publicsuffix/data/children b/vendor/golang.org/x/net/publicsuffix/data/children new file mode 100644 index 000000000..08261bffd Binary files /dev/null and b/vendor/golang.org/x/net/publicsuffix/data/children differ diff --git a/vendor/golang.org/x/net/publicsuffix/data/nodes b/vendor/golang.org/x/net/publicsuffix/data/nodes new file mode 100644 index 000000000..1dae6ede8 Binary files /dev/null and b/vendor/golang.org/x/net/publicsuffix/data/nodes differ diff --git a/vendor/golang.org/x/net/publicsuffix/data/text b/vendor/golang.org/x/net/publicsuffix/data/text new file mode 100644 index 000000000..7e516413f --- /dev/null +++ b/vendor/golang.org/x/net/publicsuffix/data/text @@ -0,0 +1 @@ +birkenesoddtangentinglogoweirbitbucketrzynishikatakayamatta-varjjatjomembersaltdalovepopartysfjordiskussionsbereichatinhlfanishikatsuragitappassenger-associationishikawazukamiokameokamakurazakitaurayasudabitternidisrechtrainingloomy-routerbjarkoybjerkreimdbalsan-suedtirololitapunkapsienamsskoganeibmdeveloperauniteroirmemorialombardiadempresashibetsukumiyamagasakinderoyonagunicloudevelopmentaxiijimarriottayninhaccanthobby-siteval-d-aosta-valleyoriikaracolognebinatsukigataiwanumatajimidsundgcahcesuolocustomer-ocimperiautoscanalytics-gatewayonagoyaveroykenflfanpachihayaakasakawaiishopitsitemasekd1kappenginedre-eikerimo-siemenscaledekaascolipicenoboribetsucks3-eu-west-3utilities-16-balestrandabergentappsseekloges3-eu-west-123paginawebcamauction-acornfshostrodawaraktyubinskaunicommbank123kotisivultrobjectselinogradimo-i-rana4u2-localhostrolekanieruchomoscientistordal-o-g-i-nikolaevents3-ap-northeast-2-ddnsking123homepagefrontappchizip61123saitamakawababia-goracleaningheannakadomarineat-urlimanowarudakuneustarostwodzislawdev-myqnapcloudcontrolledgesuite-stagingdyniamusementdllclstagehirnikonantomobelementorayokosukanoyakumoliserniaurland-4-salernord-aurdalipaywhirlimiteddnslivelanddnss3-ap-south-123siteweberlevagangaviikanonji234lima-cityeats3-ap-southeast-123webseiteambulancechireadmyblogspotaribeiraogakicks-assurfakefurniturealmpmninoheguribigawaurskog-holandinggfarsundds3-ap-southeast-20001wwwedeployokote123hjemmesidealerdalaheadjuegoshikibichuobiraustevollimombetsupplyokoze164-balena-devices3-ca-central-123websiteleaf-south-12hparliamentatsunobninsk8s3-eu-central-1337bjugnishimerablackfridaynightjxn--11b4c3ditchyouripatriabloombergretaijindustriesteinkjerbloxcmsaludivtasvuodnakaiwanairlinekobayashimodatecnologiablushakotanishinomiyashironomniwebview-assetsalvadorbmoattachmentsamegawabmsamnangerbmwellbeingzonebnrweatherchannelsdvrdnsamparalleluxenishinoomotegotsukishiwadavvenjargamvikarpaczest-a-la-maisondre-landivttasvuotnakamai-stagingloppennebomlocalzonebonavstackartuzybondigitaloceanspacesamsclubartowest1-usamsunglugsmall-webspacebookonlineboomlaakesvuemielecceboschristmasakilatiron-riopretoeidsvollovesickaruizawabostik-serverrankoshigayachtsandvikcoromantovalle-d-aostakinouebostonakijinsekikogentlentapisa-geekarumaifmemsetkmaxxn--12c1fe0bradescotksatmpaviancapitalonebouncemerckmsdscloudiybounty-fullensakerrypropertiesangovtoyosatoyokawaboutiquebecologialaichaugiangmbhartiengiangminakamichiharaboutireservdrangedalpusercontentoyotapfizerboyfriendoftheinternetflixn--12cfi8ixb8lublindesnesanjosoyrovnoticiasannanishinoshimattelemarkasaokamikitayamatsurinfinitigopocznore-og-uvdalucaniabozen-sudtiroluccanva-appstmnishiokoppegardray-dnsupdaterbozen-suedtirolukowesteuropencraftoyotomiyazakinsurealtypeformesswithdnsannohekinanporovigonohejinternationaluroybplacedogawarabikomaezakirunordkappgfoggiabrandrayddns5ybrasiliadboxoslockerbresciaogashimadachicappadovaapstemp-dnswatchest-mon-blogueurodirumagazinebrindisiciliabroadwaybroke-itvedestrandraydnsanokashibatakashimashikiyosatokigawabrokerbrothermesserlifestylebtimnetzpisdnpharmaciensantamariakebrowsersafetymarketingmodumetacentrumeteorappharmacymruovatlassian-dev-builderschaefflerbrumunddalutskashiharabrusselsantoandreclaimsanukintlon-2bryanskiptveterinaireadthedocsaobernardovre-eikerbrynebwestus2bzhitomirbzzwhitesnowflakecommunity-prochowicecomodalenissandoycompanyaarphdfcbankasumigaurawa-mazowszexn--1ck2e1bambinagisobetsuldalpha-myqnapcloudaccess3-us-east-2ixboxeroxfinityolasiteastus2comparemarkerryhotelsaves-the-whalessandria-trani-barletta-andriatranibarlettaandriacomsecaasnesoddeno-stagingrondarcondoshifteditorxn--1ctwolominamatarnobrzegrongrossetouchijiwadedyn-berlincolnissayokoshibahikariyaltakazakinzais-a-bookkeepermarshallstatebankasuyalibabahccavuotnagaraholtaleniwaizumiotsurugashimaintenanceomutazasavonarviikaminoyamaxunispaceconferenceconstructionflashdrivefsncf-ipfsaxoconsuladobeio-static-accesscamdvrcampaniaconsultantranoyconsultingroundhandlingroznysaitohnoshookuwanakayamangyshlakdnepropetrovskanlandyndns-freeboxostrowwlkpmgrphilipsyno-dschokokekscholarshipschoolbusinessebycontactivetrailcontagematsubaravendbambleborkdalvdalcest-le-patron-rancherkasydneyukuhashimokawavoues3-sa-east-1contractorskenissedalcookingruecoolblogdnsfor-better-thanhhoarairforcentralus-1cooperativano-frankivskodjeephonefosschoolsztynsetransiphotographysiocoproductionschulplattforminamiechizenisshingucciprianiigatairaumalatvuopmicrolightinguidefinimaringatlancastercorsicafjschulservercosenzakopanecosidnshome-webservercellikescandypopensocialcouchpotatofrieschwarzgwangjuh-ohtawaramotoineppueblockbusternopilawacouncilcouponscrapper-sitecozoravennaharimalborkaszubytemarketscrappinguitarscrysecretrosnubananarepublic-inquiryurihonjoyenthickaragandaxarnetbankanzakiwielunnerepairbusanagochigasakishimabarakawaharaolbia-tempio-olbiatempioolbialowiezachpomorskiengiangjesdalolipopmcdirepbodyn53cqcxn--1lqs03niyodogawacrankyotobetsumidaknongujaratmallcrdyndns-homednscwhminamifuranocreditcardyndns-iphutholdingservehttpbincheonl-ams-1creditunionionjukujitawaravpagecremonashorokanaiecrewhoswholidaycricketnedalcrimeast-kazakhstanangercrotonecrowniphuyencrsvp4cruiseservehumourcuisinellair-traffic-controllagdenesnaaseinet-freakserveircasertainaircraftingvolloansnasaarlanduponthewifidelitypedreamhostersaotomeldaluxurycuneocupcakecuritibacgiangiangryggeecurvalled-aostargets-itranslatedyndns-mailcutegirlfriendyndns-office-on-the-webhoptogurafedoraprojectransurlfeirafembetsukuis-a-bruinsfanfermodenakasatsunairportrapaniizaferraraferraris-a-bulls-fanferrerotikagoshimalopolskanittedalfetsundyndns-wikimobetsumitakagildeskaliszkolamericanfamilydservemp3fgunmaniwamannorth-kazakhstanfhvalerfilegear-augustowiiheyakagefilegear-deatnuniversitysvardofilegear-gbizfilegear-iefilegear-jpmorgangwonporterfilegear-sg-1filminamiizukamiminefinalchikugokasellfyis-a-candidatefinancefinnoyfirebaseappiemontefirenetlifylkesbiblackbaudcdn-edgestackhero-networkinggroupowiathletajimabaria-vungtaudiopsysharpigboatshawilliamhillfirenzefirestonefireweblikes-piedmontravelersinsurancefirmdalegalleryfishingoldpoint2thisamitsukefitjarfitnessettsurugiminamimakis-a-catererfjalerfkatsushikabeebyteappilottonsberguovdageaidnunjargausdalflekkefjordyndns-workservep2phxn--1lqs71dyndns-remotewdyndns-picserveminecraftransporteflesbergushikamifuranorthflankatsuyamashikokuchuoflickragerokunohealthcareershellflierneflirfloginlinefloppythonanywherealtorfloraflorencefloripalmasfjordenfloristanohatajiris-a-celticsfanfloromskogxn--2m4a15eflowershimokitayamafltravinhlonganflynnhosting-clusterfncashgabadaddjabbottoyourafndyndns1fnwkzfolldalfoolfor-ourfor-somegurownproviderfor-theaterfordebianforexrotheworkpccwinbar0emmafann-arborlandd-dnsiskinkyowariasahikawarszawashtenawsmppl-wawsglobalacceleratorahimeshimakanegasakievennodebalancern4t3l3p0rtatarantours3-ap-northeast-123minsidaarborteaches-yogano-ipifony-123miwebaccelastx4432-b-datacenterprisesakijobservableusercontentateshinanomachintaifun-dnsdojournalistoloseyouriparisor-fronavuotnarashinoharaetnabudejjunipereggio-emilia-romagnaroyboltateyamajureggiocalabriakrehamnayoro0o0forgotdnshimonitayanagithubpreviewsaikisarazure-mobileirfjordynnservepicservequakeforli-cesena-forlicesenaforlillehammerfeste-ipimientaketomisatoolshimonosekikawaforsalegoismailillesandefjordynservebbservesarcasmileforsandasuolodingenfortalfortefosneshimosuwalkis-a-chefashionstorebaseljordyndns-serverisignfotrdynulvikatowicefoxn--2scrj9casinordlandurbanamexnetgamersapporomurafozfr-1fr-par-1fr-par-2franamizuhoboleslawiecommerce-shoppingyeongnamdinhachijohanamakisofukushimaoris-a-conservativegarsheiheijis-a-cparachutingfredrikstadynv6freedesktopazimuthaibinhphuocelotenkawakayamagnetcieszynh-servebeero-stageiseiroumugifuchungbukharag-cloud-championshiphoplixn--30rr7yfreemyiphosteurovisionredumbrellangevagrigentobishimadridvagsoygardenebakkeshibechambagricoharugbydgoszczecin-berlindasdaburfreesitefreetlshimotsukefreisennankokubunjis-a-cubicle-slavellinodeobjectshimotsumafrenchkisshikindleikangerfreseniushinichinanfriuli-v-giuliafriuli-ve-giuliafriuli-vegiuliafriuli-venezia-giuliafriuli-veneziagiuliafriuli-vgiuliafriuliv-giuliafriulive-giuliafriulivegiuliafriulivenezia-giuliafriuliveneziagiuliafriulivgiuliafrlfroganshinjotelulubin-vpncateringebunkyonanaoshimamateramockashiwarafrognfrolandynvpnpluservicesevastopolitiendafrom-akamaized-stagingfrom-alfrom-arfrom-azurewebsiteshikagamiishibuyabukihokuizumobaragusabaerobaticketshinjukuleuvenicefrom-campobassociatest-iserveblogsytenrissadistdlibestadultrentin-sudtirolfrom-coachaseljeducationcillahppiacenzaganfrom-ctrentin-sued-tirolfrom-dcatfooddagestangefrom-decagliarikuzentakataikillfrom-flapymntrentin-suedtirolfrom-gap-east-1from-higashiagatsumagoianiafrom-iafrom-idyroyrvikingulenfrom-ilfrom-in-the-bandairtelebitbridgestonemurorangecloudplatform0from-kshinkamigototalfrom-kyfrom-langsonyantakahamalselveruminamiminowafrom-malvikaufentigerfrom-mdfrom-mein-vigorlicefrom-mifunefrom-mnfrom-modshinshinotsurgeryfrom-mshinshirofrom-mtnfrom-ncatholicurus-4from-ndfrom-nefrom-nhs-heilbronnoysundfrom-njshintokushimafrom-nminamioguni5from-nvalledaostargithubusercontentrentino-a-adigefrom-nycaxiaskvollpagesardegnarutolgaulardalvivanovoldafrom-ohdancefrom-okegawassamukawataris-a-democratrentino-aadigefrom-orfrom-panasonichernovtsykkylvenneslaskerrylogisticsardiniafrom-pratohmamurogawatsonrenderfrom-ris-a-designerimarugame-hostyhostingfrom-schmidtre-gauldalfrom-sdfrom-tnfrom-txn--32vp30hachinoheavyfrom-utsiracusagaeroclubmedecin-addrammenuorodoyerfrom-val-daostavalleyfrom-vtrentino-alto-adigefrom-wafrom-wiardwebthingsjcbnpparibashkiriafrom-wvallee-aosteroyfrom-wyfrosinonefrostabackplaneapplebesbyengerdalp1froyal-commissionfruskydivingfujiiderafujikawaguchikonefujiminokamoenairtrafficplexus-2fujinomiyadapliefujiokazakinkobearalvahkikonaibetsubame-south-1fujisatoshoeshintomikasaharafujisawafujishiroishidakabiratoridediboxn--3bst00minamisanrikubetsupportrentino-altoadigefujitsuruokakamigaharafujiyoshidappnodearthainguyenfukayabeardubaikawagoefukuchiyamadatsunanjoburgfukudomigawafukuis-a-doctorfukumitsubishigakirkeneshinyoshitomiokamisatokamachippubetsuikitchenfukuokakegawafukuroishikariwakunigamigrationfukusakirovogradoyfukuyamagatakaharunusualpersonfunabashiriuchinadattorelayfunagatakahashimamakiryuohkurafunahashikamiamakusatsumasendaisenergyeongginowaniihamatamakinoharafundfunkfeuerfuoiskujukuriyamandalfuosskoczowindowskrakowinefurubirafurudonordreisa-hockeynutwentertainmentrentino-s-tirolfurukawajimangolffanshiojirishirifujiedafusoctrangfussagamiharafutabayamaguchinomihachimanagementrentino-stirolfutboldlygoingnowhere-for-more-og-romsdalfuttsurutashinais-a-financialadvisor-aurdalfuturecmshioyamelhushirahamatonbetsurnadalfuturehostingfuturemailingfvghakuis-a-gurunzenhakusandnessjoenhaldenhalfmoonscalebookinghostedpictetrentino-sud-tirolhalsakakinokiaham-radio-opinbar1hamburghammarfeastasiahamurakamigoris-a-hard-workershiraokamisunagawahanamigawahanawahandavvesiidanangodaddyn-o-saurealestatefarmerseinehandcrafteducatorprojectrentino-sudtirolhangglidinghangoutrentino-sued-tirolhannannestadhannosegawahanoipinkazohanyuzenhappouzshiratakahagianghasamap-northeast-3hasaminami-alpshishikuis-a-hunterhashbanghasudazaifudaigodogadobeioruntimedio-campidano-mediocampidanomediohasura-appinokokamikoaniikappudopaashisogndalhasvikazteleportrentino-suedtirolhatogayahoooshikamagayaitakamoriokakudamatsuehatoyamazakitahiroshimarcheapartmentshisuifuettertdasnetzhatsukaichikaiseiyoichipshitaramahattfjelldalhayashimamotobusells-for-lesshizukuishimoichilloutsystemscloudsitehazuminobushibukawahelplfinancialhelsinkitakamiizumisanofidonnakamurataitogliattinnhemneshizuokamitondabayashiogamagoriziahemsedalhepforgeblockshoujis-a-knightpointtokaizukamaishikshacknetrentinoa-adigehetemlbfanhigashichichibuzentsujiiehigashihiroshimanehigashiizumozakitakatakanabeautychyattorneyagawakkanaioirasebastopoleangaviikadenagahamaroyhigashikagawahigashikagurasoedahigashikawakitaaikitakyushunantankazunovecorebungoonow-dnshowahigashikurumeinforumzhigashimatsushimarnardalhigashimatsuyamakitaakitadaitoigawahigashimurayamamotorcycleshowtimeloyhigashinarusells-for-uhigashinehigashiomitamanoshiroomghigashiosakasayamanakakogawahigashishirakawamatakanezawahigashisumiyoshikawaminamiaikitamihamadahigashitsunospamproxyhigashiurausukitamotosunnydayhigashiyamatokoriyamanashiibaclieu-1higashiyodogawahigashiyoshinogaris-a-landscaperspectakasakitanakagusukumoldeliveryhippyhiraizumisatohokkaidontexistmein-iservschulecznakaniikawatanagurahirakatashinagawahiranais-a-lawyerhirarahiratsukaeruhirayaizuwakamatsubushikusakadogawahitachiomiyaginozawaonsensiositehitachiotaketakaokalmykiahitraeumtgeradegreehjartdalhjelmelandholyhomegoodshwinnersiiitesilkddiamondsimple-urlhomeipioneerhomelinkyard-cloudjiffyresdalhomelinuxn--3ds443ghomeofficehomesecuritymacaparecidahomesecuritypchiryukyuragiizehomesenseeringhomeskleppippugliahomeunixn--3e0b707ehondahonjyoitakarazukaluganskfh-muensterhornindalhorsells-itrentinoaadigehortendofinternet-dnsimplesitehospitalhotelwithflightsirdalhotmailhoyangerhoylandetakasagooglecodespotrentinoalto-adigehungyenhurdalhurumajis-a-liberalhyllestadhyogoris-a-libertarianhyugawarahyundaiwafuneis-very-evillasalleitungsenis-very-goodyearis-very-niceis-very-sweetpepperugiais-with-thebandoomdnstraceisk01isk02jenv-arubacninhbinhdinhktistoryjeonnamegawajetztrentinostiroljevnakerjewelryjgorajlljls-sto1jls-sto2jls-sto3jmpixolinodeusercontentrentinosud-tiroljnjcloud-ver-jpchitosetogitsuliguriajoyokaichibahcavuotnagaivuotnagaokakyotambabymilk3jozis-a-musicianjpnjprsolarvikhersonlanxessolundbeckhmelnitskiyamasoykosaigawakosakaerodromegalloabatobamaceratachikawafaicloudineencoreapigeekoseis-a-painterhostsolutionslupskhakassiakosheroykoshimizumakis-a-patsfankoshughesomakosugekotohiradomainstitutekotourakouhokumakogenkounosupersalevangerkouyamasudakouzushimatrixn--3pxu8khplaystation-cloudyclusterkozagawakozakis-a-personaltrainerkozowiosomnarviklabudhabikinokawachinaganoharamcocottekpnkppspbarcelonagawakepnord-odalwaysdatabaseballangenkainanaejrietisalatinabenogiehtavuoatnaamesjevuemielnombrendlyngen-rootaruibxos3-us-gov-west-1krasnikahokutokonamegatakatoris-a-photographerokussldkrasnodarkredstonekrelliankristiansandcatsoowitdkmpspawnextdirectrentinosudtirolkristiansundkrodsheradkrokstadelvaldaostavangerkropyvnytskyis-a-playershiftcryptonomichinomiyakekryminamiyamashirokawanabelaudnedalnkumamotoyamatsumaebashimofusakatakatsukis-a-republicanonoichinosekigaharakumanowtvaokumatorinokumejimatsumotofukekumenanyokkaichirurgiens-dentistes-en-francekundenkunisakis-a-rockstarachowicekunitachiaraisaijolsterkunitomigusukukis-a-socialistgstagekunneppubtlsopotrentinosued-tirolkuokgroupizzakurgankurobegetmyipirangalluplidlugolekagaminorddalkurogimimozaokinawashirosatochiokinoshimagentositempurlkuroisodegaurakuromatsunais-a-soxfankuronkurotakikawasakis-a-studentalkushirogawakustanais-a-teacherkassyncloudkusuppliesor-odalkutchanelkutnokuzumakis-a-techietipslzkvafjordkvalsundkvamsterdamnserverbaniakvanangenkvinesdalkvinnheradkviteseidatingkvitsoykwpspdnsor-varangermishimatsusakahogirlymisugitokorozawamitakeharamitourismartlabelingmitoyoakemiuramiyazurecontainerdpoliticaobangmiyotamatsukuris-an-actormjondalenmonzabrianzaramonzaebrianzamonzaedellabrianzamordoviamorenapolicemoriyamatsuuramoriyoshiminamiashigaramormonstermoroyamatsuzakis-an-actressmushcdn77-sslingmortgagemoscowithgoogleapiszmoseushimogosenmosjoenmoskenesorreisahayakawakamiichikawamisatottoris-an-anarchistjordalshalsenmossortlandmosviknx-serversusakiyosupabaseminemotegit-reposoruminanomoviemovimientokyotangotembaixadattowebhareidsbergmozilla-iotrentinosuedtirolmtranbytomaridagawalmartrentinsud-tirolmuikaminokawanishiaizubangemukoelnmunakatanemuosattemupkomatsushimassa-carrara-massacarraramassabuzzmurmanskomforbar2murotorcraftranakatombetsumy-gatewaymusashinodesakegawamuseumincomcastoripressorfoldmusicapetownnews-stagingmutsuzawamy-vigormy-wanggoupilemyactivedirectorymyamazeplaymyasustor-elvdalmycdmycloudnsoundcastorjdevcloudfunctionsokndalmydattolocalcertificationmyddnsgeekgalaxymydissentrentinsudtirolmydobissmarterthanyoumydrobofageometre-experts-comptablesowamydspectruminisitemyeffectrentinsued-tirolmyfastly-edgekey-stagingmyfirewalledreplittlestargardmyforuminterecifedextraspace-to-rentalstomakomaibaramyfritzmyftpaccesspeedpartnermyhome-servermyjinomykolaivencloud66mymailermymediapchoseikarugalsacemyokohamamatsudamypeplatformsharis-an-artistockholmestrandmypetsphinxn--41amyphotoshibajddarvodkafjordvaporcloudmypictureshinomypsxn--42c2d9amysecuritycamerakermyshopblockspjelkavikommunalforbundmyshopifymyspreadshopselectrentinsuedtirolmytabitordermythic-beastspydebergmytis-a-anarchistg-buildermytuleap-partnersquaresindevicenzamyvnchoshichikashukudoyamakeuppermywirecipescaracallypoivronpokerpokrovskommunepolkowicepoltavalle-aostavernpomorzeszowithyoutuberspacekitagawaponpesaro-urbino-pesarourbinopesaromasvuotnaritakurashikis-bykleclerchitachinakagawaltervistaipeigersundynamic-dnsarlpordenonepornporsangerporsangugeporsgrunnanpoznanpraxihuanprdprgmrprimetelprincipeprivatelinkomonowruzhgorodeoprivatizehealthinsuranceprofesionalprogressivegasrlpromonza-e-della-brianzaptokuyamatsushigepropertysnesrvarggatrevisogneprotectionprotonetroandindependent-inquest-a-la-masionprudentialpruszkowiwatsukiyonotaireserve-onlineprvcyonabarumbriaprzeworskogpunyufuelpupulawypussycatanzarowixsitepvhachirogatakahatakaishimojis-a-geekautokeinotteroypvtrogstadpwchowderpzqhadanorthwesternmutualqldqotoyohashimotoshimaqponiatowadaqslgbtroitskomorotsukagawaqualifioapplatter-applatterplcube-serverquangngais-certifiedugit-pagespeedmobilizeroticaltanissettailscaleforcequangninhthuanquangtritonoshonais-foundationquickconnectromsakuragawaquicksytestreamlitapplumbingouvaresearchitectesrhtrentoyonakagyokutoyakomakizunokunimimatakasugais-an-engineeringquipelementstrippertuscanytushungrytuvalle-daostamayukis-into-animeiwamizawatuxfamilytuyenquangbinhthuantwmailvestnesuzukis-gonevestre-slidreggio-calabriavestre-totennishiawakuravestvagoyvevelstadvibo-valentiaavibovalentiavideovinhphuchromedicinagatorogerssarufutsunomiyawakasaikaitakokonoevinnicarbonia-iglesias-carboniaiglesiascarboniavinnytsiavipsinaapplurinacionalvirginanmokurennebuvirtual-userveexchangevirtualservervirtualuserveftpodhalevisakurais-into-carsnoasakuholeckodairaviterboliviajessheimmobilienvivianvivoryvixn--45br5cylvlaanderennesoyvladikavkazimierz-dolnyvladimirvlogintoyonezawavmintsorocabalashovhachiojiyahikobierzycevologdanskoninjambylvolvolkswagencyouvolyngdalvoorlopervossevangenvotevotingvotoyonovps-hostrowiechungnamdalseidfjordynathomebuiltwithdarkhangelskypecorittogojomeetoystre-slidrettozawawmemergencyahabackdropalermochizukikirarahkkeravjuwmflabsvalbardunloppadualstackomvuxn--3hcrj9chonanbuskerudynamisches-dnsarpsborgripeeweeklylotterywoodsidellogliastradingworse-thanhphohochiminhadselbuyshouseshirakolobrzegersundongthapmircloudletshiranukamishihorowowloclawekonskowolawawpdevcloudwpenginepoweredwphostedmailwpmucdnipropetrovskygearappodlasiellaknoluoktagajobojis-an-entertainerwpmudevcdnaccessojamparaglidingwritesthisblogoipodzonewroclawmcloudwsseoullensvanguardianwtcp4wtfastlylbanzaicloudappspotagereporthruherecreationinomiyakonojorpelandigickarasjohkameyamatotakadawuozuerichardlillywzmiuwajimaxn--4it797konsulatrobeepsondriobranconagareyamaizuruhrxn--4pvxs4allxn--54b7fta0ccistrondheimpertrixcdn77-secureadymadealstahaugesunderxn--55qw42gxn--55qx5dxn--5dbhl8dxn--5js045dxn--5rtp49citadelhichisochimkentozsdell-ogliastraderxn--5rtq34kontuminamiuonumatsunoxn--5su34j936bgsgxn--5tzm5gxn--6btw5axn--6frz82gxn--6orx2rxn--6qq986b3xlxn--7t0a264citicarrdrobakamaiorigin-stagingmxn--12co0c3b4evalleaostaobaomoriguchiharaffleentrycloudflare-ipfstcgroupaaskimitsubatamibulsan-suedtirolkuszczytnoopscbgrimstadrrxn--80aaa0cvacationsvchoyodobashichinohealth-carereforminamidaitomanaustdalxn--80adxhksveioxn--80ao21axn--80aqecdr1axn--80asehdbarclaycards3-us-west-1xn--80aswgxn--80aukraanghkeliwebpaaskoyabeagleboardxn--8dbq2axn--8ltr62konyvelohmusashimurayamassivegridxn--8pvr4uxn--8y0a063axn--90a1affinitylotterybnikeisencowayxn--90a3academiamicable-modemoneyxn--90aeroportsinfolionetworkangerxn--90aishobaraxn--90amckinseyxn--90azhytomyrxn--9dbq2axn--9et52uxn--9krt00axn--andy-iraxn--aroport-byanagawaxn--asky-iraxn--aurskog-hland-jnbarclays3-us-west-2xn--avery-yuasakurastoragexn--b-5gaxn--b4w605ferdxn--balsan-sdtirol-nsbsvelvikongsbergxn--bck1b9a5dre4civilaviationfabricafederation-webredirectmediatechnologyeongbukashiwazakiyosembokutamamuraxn--bdddj-mrabdxn--bearalvhki-y4axn--berlevg-jxaxn--bhcavuotna-s4axn--bhccavuotna-k7axn--bidr-5nachikatsuuraxn--bievt-0qa2xn--bjarky-fyanaizuxn--bjddar-ptarumizusawaxn--blt-elabcienciamallamaceiobbcn-north-1xn--bmlo-graingerxn--bod-2natalxn--bozen-sdtirol-2obanazawaxn--brnny-wuacademy-firewall-gatewayxn--brnnysund-m8accident-investigation-aptibleadpagesquare7xn--brum-voagatrustkanazawaxn--btsfjord-9zaxn--bulsan-sdtirol-nsbarefootballooningjovikarasjoketokashikiyokawaraxn--c1avgxn--c2br7gxn--c3s14misakis-a-therapistoiaxn--cck2b3baremetalombardyn-vpndns3-website-ap-northeast-1xn--cckwcxetdxn--cesena-forl-mcbremangerxn--cesenaforl-i8axn--cg4bkis-into-cartoonsokamitsuexn--ciqpnxn--clchc0ea0b2g2a9gcdxn--czr694bargainstantcloudfrontdoorestauranthuathienhuebinordre-landiherokuapparochernigovernmentjeldsundiscordsays3-website-ap-southeast-1xn--czrs0trvaroyxn--czru2dxn--czrw28barrel-of-knowledgeapplinziitatebayashijonawatebizenakanojoetsumomodellinglassnillfjordiscordsezgoraxn--d1acj3barrell-of-knowledgecomputermezproxyzgorzeleccoffeedbackanagawarmiastalowa-wolayangroupars3-website-ap-southeast-2xn--d1alfaststacksevenassigdalxn--d1atrysiljanxn--d5qv7z876clanbibaiduckdnsaseboknowsitallxn--davvenjrga-y4axn--djrs72d6uyxn--djty4koobindalxn--dnna-grajewolterskluwerxn--drbak-wuaxn--dyry-iraxn--e1a4cldmail-boxaxn--eckvdtc9dxn--efvn9svn-repostuff-4-salexn--efvy88haebaruericssongdalenviknaklodzkochikushinonsenasakuchinotsuchiurakawaxn--ehqz56nxn--elqq16hagakhanhhoabinhduongxn--eveni-0qa01gaxn--f6qx53axn--fct429kooris-a-nascarfanxn--fhbeiarnxn--finny-yuaxn--fiq228c5hsbcleverappsassarinuyamashinazawaxn--fiq64barsycenterprisecloudcontrolappgafanquangnamasteigenoamishirasatochigifts3-website-eu-west-1xn--fiqs8swidnicaravanylvenetogakushimotoganexn--fiqz9swidnikitagatakkomaganexn--fjord-lraxn--fjq720axn--fl-ziaxn--flor-jraxn--flw351exn--forl-cesena-fcbsswiebodzindependent-commissionxn--forlcesena-c8axn--fpcrj9c3dxn--frde-granexn--frna-woaxn--frya-hraxn--fzc2c9e2clickrisinglesjaguarxn--fzys8d69uvgmailxn--g2xx48clinicasacampinagrandebungotakadaemongolianishitosashimizunaminamiawajikintuitoyotsukaidownloadrudtvsaogoncapooguyxn--gckr3f0fastvps-serveronakanotoddenxn--gecrj9cliniquedaklakasamatsudoesntexisteingeekasserversicherungroks-theatrentin-sud-tirolxn--ggaviika-8ya47hagebostadxn--gildeskl-g0axn--givuotna-8yandexcloudxn--gjvik-wuaxn--gk3at1exn--gls-elacaixaxn--gmq050is-into-gamessinamsosnowieconomiasadojin-dslattuminamitanexn--gmqw5axn--gnstigbestellen-zvbrplsbxn--45brj9churcharterxn--gnstigliefern-wobihirosakikamijimayfirstorfjordxn--h-2failxn--h1ahnxn--h1alizxn--h2breg3eveneswinoujsciencexn--h2brj9c8clothingdustdatadetectrani-andria-barletta-trani-andriaxn--h3cuzk1dienbienxn--hbmer-xqaxn--hcesuolo-7ya35barsyonlinehimejiiyamanouchikujoinvilleirvikarasuyamashikemrevistathellequipmentjmaxxxjavald-aostatics3-website-sa-east-1xn--hebda8basicserversejny-2xn--hery-iraxn--hgebostad-g3axn--hkkinen-5waxn--hmmrfeasta-s4accident-prevention-k3swisstufftoread-booksnestudioxn--hnefoss-q1axn--hobl-iraxn--holtlen-hxaxn--hpmir-xqaxn--hxt814exn--hyanger-q1axn--hylandet-54axn--i1b6b1a6a2exn--imr513nxn--indery-fyaotsusonoxn--io0a7is-leetrentinoaltoadigexn--j1adpohlxn--j1aefauskedsmokorsetagayaseralingenovaraxn--j1ael8basilicataniaxn--j1amhaibarakisosakitahatakamatsukawaxn--j6w193gxn--jlq480n2rgxn--jlster-byasakaiminatoyookananiimiharuxn--jrpeland-54axn--jvr189misasaguris-an-accountantsmolaquilaocais-a-linux-useranishiaritabashikaoizumizakitashiobaraxn--k7yn95exn--karmy-yuaxn--kbrq7oxn--kcrx77d1x4axn--kfjord-iuaxn--klbu-woaxn--klt787dxn--kltp7dxn--kltx9axn--klty5xn--45q11circlerkstagentsasayamaxn--koluokta-7ya57haiduongxn--kprw13dxn--kpry57dxn--kput3is-lostre-toteneis-a-llamarumorimachidaxn--krager-gyasugitlabbvieeexn--kranghke-b0axn--krdsherad-m8axn--krehamn-dxaxn--krjohka-hwab49jdfastly-terrariuminamiiseharaxn--ksnes-uuaxn--kvfjord-nxaxn--kvitsy-fyasuokanmakiwakuratexn--kvnangen-k0axn--l-1fairwindsynology-diskstationxn--l1accentureklamborghinikkofuefukihabororosynology-dsuzakadnsaliastudynaliastrynxn--laheadju-7yatominamibosoftwarendalenugxn--langevg-jxaxn--lcvr32dxn--ldingen-q1axn--leagaviika-52basketballfinanzjaworznoticeableksvikaratsuginamikatagamilanotogawaxn--lesund-huaxn--lgbbat1ad8jejuxn--lgrd-poacctulaspeziaxn--lhppi-xqaxn--linds-pramericanexpresservegame-serverxn--loabt-0qaxn--lrdal-sraxn--lrenskog-54axn--lt-liacn-northwest-1xn--lten-granvindafjordxn--lury-iraxn--m3ch0j3axn--mely-iraxn--merker-kuaxn--mgb2ddesxn--mgb9awbfbsbxn--1qqw23axn--mgba3a3ejtunesuzukamogawaxn--mgba3a4f16axn--mgba3a4fra1-deloittexn--mgba7c0bbn0axn--mgbaakc7dvfsxn--mgbaam7a8haiphongonnakatsugawaxn--mgbab2bdxn--mgbah1a3hjkrdxn--mgbai9a5eva00batsfjordiscountry-snowplowiczeladzlgleezeu-2xn--mgbai9azgqp6jelasticbeanstalkharkovalleeaostexn--mgbayh7gparasitexn--mgbbh1a71exn--mgbc0a9azcgxn--mgbca7dzdoxn--mgbcpq6gpa1axn--mgberp4a5d4a87gxn--mgberp4a5d4arxn--mgbgu82axn--mgbi4ecexposedxn--mgbpl2fhskopervikhmelnytskyivalleedaostexn--mgbqly7c0a67fbcngroks-thisayamanobeatsaudaxn--mgbqly7cvafricargoboavistanbulsan-sudtirolxn--mgbt3dhdxn--mgbtf8flatangerxn--mgbtx2bauhauspostman-echofunatoriginstances3-website-us-east-1xn--mgbx4cd0abkhaziaxn--mix082fbx-osewienxn--mix891fbxosexyxn--mjndalen-64axn--mk0axindependent-inquiryxn--mk1bu44cnpyatigorskjervoyagexn--mkru45is-not-certifiedxn--mlatvuopmi-s4axn--mli-tlavagiskexn--mlselv-iuaxn--moreke-juaxn--mori-qsakuratanxn--mosjen-eyatsukannamihokksundxn--mot-tlavangenxn--mre-og-romsdal-qqbuservecounterstrikexn--msy-ula0hair-surveillancexn--mtta-vrjjat-k7aflakstadaokayamazonaws-cloud9guacuiababybluebiteckidsmynasushiobaracingrok-freeddnsfreebox-osascoli-picenogatabuseating-organicbcgjerdrumcprequalifymelbourneasypanelblagrarq-authgear-stagingjerstadeltaishinomakilovecollegefantasyleaguenoharauthgearappspacehosted-by-previderehabmereitattoolforgerockyombolzano-altoadigeorgeorgiauthordalandroideporteatonamidorivnebetsukubankanumazuryomitanocparmautocodebergamoarekembuchikumagayagawafflecelloisirs3-external-180reggioemiliaromagnarusawaustrheimbalsan-sudtirolivingitpagexlivornobserveregruhostingivestbyglandroverhalladeskjakamaiedge-stagingivingjemnes3-eu-west-2038xn--muost-0qaxn--mxtq1misawaxn--ngbc5azdxn--ngbe9e0axn--ngbrxn--4dbgdty6ciscofreakamaihd-stagingriwataraindroppdalxn--nit225koryokamikawanehonbetsuwanouchikuhokuryugasakis-a-nursellsyourhomeftpiwatexn--nmesjevuemie-tcbalatinord-frontierxn--nnx388axn--nodessakurawebsozais-savedxn--nqv7fs00emaxn--nry-yla5gxn--ntso0iqx3axn--ntsq17gxn--nttery-byaeservehalflifeinsurancexn--nvuotna-hwaxn--nyqy26axn--o1achernivtsicilynxn--4dbrk0cexn--o3cw4hakatanortonkotsunndalxn--o3cyx2axn--od0algardxn--od0aq3beneventodayusuharaxn--ogbpf8fldrvelvetromsohuissier-justicexn--oppegrd-ixaxn--ostery-fyatsushiroxn--osyro-wuaxn--otu796dxn--p1acfedjeezxn--p1ais-slickharkivallee-d-aostexn--pgbs0dhlx3xn--porsgu-sta26fedorainfraclouderaxn--pssu33lxn--pssy2uxn--q7ce6axn--q9jyb4cnsauheradyndns-at-homedepotenzamamicrosoftbankasukabedzin-brbalsfjordietgoryoshiokanravocats3-fips-us-gov-west-1xn--qcka1pmcpenzapposxn--qqqt11misconfusedxn--qxa6axn--qxamunexus-3xn--rady-iraxn--rdal-poaxn--rde-ulazioxn--rdy-0nabaris-uberleetrentinos-tirolxn--rennesy-v1axn--rhkkervju-01afedorapeoplefrakkestadyndns-webhostingujogaszxn--rholt-mragowoltlab-democraciaxn--rhqv96gxn--rht27zxn--rht3dxn--rht61exn--risa-5naturalxn--risr-iraxn--rland-uuaxn--rlingen-mxaxn--rmskog-byawaraxn--rny31hakodatexn--rovu88bentleyusuitatamotorsitestinglitchernihivgubs3-website-us-west-1xn--rros-graphicsxn--rskog-uuaxn--rst-0naturbruksgymnxn--rsta-framercanvasxn--rvc1e0am3exn--ryken-vuaxn--ryrvik-byawatahamaxn--s-1faitheshopwarezzoxn--s9brj9cntraniandriabarlettatraniandriaxn--sandnessjen-ogbentrendhostingliwiceu-3xn--sandy-yuaxn--sdtirol-n2axn--seral-lraxn--ses554gxn--sgne-graphoxn--4gbriminiserverxn--skierv-utazurestaticappspaceusercontentunkongsvingerxn--skjervy-v1axn--skjk-soaxn--sknit-yqaxn--sknland-fxaxn--slat-5navigationxn--slt-elabogadobeaemcloud-fr1xn--smla-hraxn--smna-gratangenxn--snase-nraxn--sndre-land-0cbeppublishproxyuufcfanirasakindependent-panelomonza-brianzaporizhzhedmarkarelianceu-4xn--snes-poaxn--snsa-roaxn--sr-aurdal-l8axn--sr-fron-q1axn--sr-odal-q1axn--sr-varanger-ggbeskidyn-ip24xn--srfold-byaxn--srreisa-q1axn--srum-gratis-a-bloggerxn--stfold-9xaxn--stjrdal-s1axn--stjrdalshalsen-sqbestbuyshoparenagasakikuchikuseihicampinashikiminohostfoldnavyuzawaxn--stre-toten-zcbetainaboxfuselfipartindependent-reviewegroweibolognagasukeu-north-1xn--t60b56axn--tckweddingxn--tiq49xqyjelenia-goraxn--tjme-hraxn--tn0agrocerydxn--tnsberg-q1axn--tor131oxn--trany-yuaxn--trentin-sd-tirol-rzbhzc66xn--trentin-sdtirol-7vbialystokkeymachineu-south-1xn--trentino-sd-tirol-c3bielawakuyachimataharanzanishiazaindielddanuorrindigenamerikawauevje-og-hornnes3-website-us-west-2xn--trentino-sdtirol-szbiella-speziaxn--trentinosd-tirol-rzbieszczadygeyachiyodaeguamfamscompute-1xn--trentinosdtirol-7vbievat-band-campaignieznoorstaplesakyotanabellunordeste-idclkarlsoyxn--trentinsd-tirol-6vbifukagawalbrzycharitydalomzaporizhzhiaxn--trentinsdtirol-nsbigv-infolkebiblegnicalvinklein-butterhcloudiscoursesalangenishigotpantheonsitexn--trgstad-r1axn--trna-woaxn--troms-zuaxn--tysvr-vraxn--uc0atventuresinstagingxn--uc0ay4axn--uist22hakonexn--uisz3gxn--unjrga-rtashkenturindalxn--unup4yxn--uuwu58axn--vads-jraxn--valle-aoste-ebbturystykaneyamazoexn--valle-d-aoste-ehboehringerikexn--valleaoste-e7axn--valledaoste-ebbvadsoccertmgreaterxn--vard-jraxn--vegrshei-c0axn--vermgensberater-ctb-hostingxn--vermgensberatung-pwbiharstadotsubetsugarulezajskiervaksdalondonetskarmoyxn--vestvgy-ixa6oxn--vg-yiabruzzombieidskogasawarackmazerbaijan-mayenbaidarmeniaxn--vgan-qoaxn--vgsy-qoa0jellybeanxn--vgu402coguchikuzenishiwakinvestmentsaveincloudyndns-at-workisboringsakershusrcfdyndns-blogsitexn--vhquvestfoldxn--vler-qoaxn--vre-eiker-k8axn--vrggt-xqadxn--vry-yla5gxn--vuq861bihoronobeokagakikugawalesundiscoverdalondrinaplesknsalon-1xn--w4r85el8fhu5dnraxn--w4rs40lxn--wcvs22dxn--wgbh1communexn--wgbl6axn--xhq521bikedaejeonbuk0xn--xkc2al3hye2axn--xkc2dl3a5ee0hakubackyardshiraois-a-greenxn--y9a3aquarelleasingxn--yer-znavois-very-badxn--yfro4i67oxn--ygarden-p1axn--ygbi2ammxn--4it168dxn--ystre-slidre-ujbiofficialorenskoglobodoes-itcouldbeworldishangrilamdongnairkitapps-audibleasecuritytacticsxn--0trq7p7nnishiharaxn--zbx025dxn--zf0ao64axn--zf0avxlxn--zfr164bipartsaloonishiizunazukindustriaxnbayernxz \ No newline at end of file diff --git a/vendor/golang.org/x/net/publicsuffix/list.go b/vendor/golang.org/x/net/publicsuffix/list.go new file mode 100644 index 000000000..d56e9e762 --- /dev/null +++ b/vendor/golang.org/x/net/publicsuffix/list.go @@ -0,0 +1,203 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:generate go run gen.go + +// Package publicsuffix provides a public suffix list based on data from +// https://publicsuffix.org/ +// +// A public suffix is one under which Internet users can directly register +// names. It is related to, but different from, a TLD (top level domain). +// +// "com" is a TLD (top level domain). Top level means it has no dots. +// +// "com" is also a public suffix. Amazon and Google have registered different +// siblings under that domain: "amazon.com" and "google.com". +// +// "au" is another TLD, again because it has no dots. But it's not "amazon.au". +// Instead, it's "amazon.com.au". +// +// "com.au" isn't an actual TLD, because it's not at the top level (it has +// dots). But it is an eTLD (effective TLD), because that's the branching point +// for domain name registrars. +// +// Another name for "an eTLD" is "a public suffix". Often, what's more of +// interest is the eTLD+1, or one more label than the public suffix. For +// example, browsers partition read/write access to HTTP cookies according to +// the eTLD+1. Web pages served from "amazon.com.au" can't read cookies from +// "google.com.au", but web pages served from "maps.google.com" can share +// cookies from "www.google.com", so you don't have to sign into Google Maps +// separately from signing into Google Web Search. Note that all four of those +// domains have 3 labels and 2 dots. The first two domains are each an eTLD+1, +// the last two are not (but share the same eTLD+1: "google.com"). +// +// All of these domains have the same eTLD+1: +// - "www.books.amazon.co.uk" +// - "books.amazon.co.uk" +// - "amazon.co.uk" +// +// Specifically, the eTLD+1 is "amazon.co.uk", because the eTLD is "co.uk". +// +// There is no closed form algorithm to calculate the eTLD of a domain. +// Instead, the calculation is data driven. This package provides a +// pre-compiled snapshot of Mozilla's PSL (Public Suffix List) data at +// https://publicsuffix.org/ +package publicsuffix // import "golang.org/x/net/publicsuffix" + +// TODO: specify case sensitivity and leading/trailing dot behavior for +// func PublicSuffix and func EffectiveTLDPlusOne. + +import ( + "fmt" + "net/http/cookiejar" + "strings" +) + +// List implements the cookiejar.PublicSuffixList interface by calling the +// PublicSuffix function. +var List cookiejar.PublicSuffixList = list{} + +type list struct{} + +func (list) PublicSuffix(domain string) string { + ps, _ := PublicSuffix(domain) + return ps +} + +func (list) String() string { + return version +} + +// PublicSuffix returns the public suffix of the domain using a copy of the +// publicsuffix.org database compiled into the library. +// +// icann is whether the public suffix is managed by the Internet Corporation +// for Assigned Names and Numbers. If not, the public suffix is either a +// privately managed domain (and in practice, not a top level domain) or an +// unmanaged top level domain (and not explicitly mentioned in the +// publicsuffix.org list). For example, "foo.org" and "foo.co.uk" are ICANN +// domains, "foo.dyndns.org" and "foo.blogspot.co.uk" are private domains and +// "cromulent" is an unmanaged top level domain. +// +// Use cases for distinguishing ICANN domains like "foo.com" from private +// domains like "foo.appspot.com" can be found at +// https://wiki.mozilla.org/Public_Suffix_List/Use_Cases +func PublicSuffix(domain string) (publicSuffix string, icann bool) { + lo, hi := uint32(0), uint32(numTLD) + s, suffix, icannNode, wildcard := domain, len(domain), false, false +loop: + for { + dot := strings.LastIndex(s, ".") + if wildcard { + icann = icannNode + suffix = 1 + dot + } + if lo == hi { + break + } + f := find(s[1+dot:], lo, hi) + if f == notFound { + break + } + + u := uint32(nodes.get(f) >> (nodesBitsTextOffset + nodesBitsTextLength)) + icannNode = u&(1<>= nodesBitsICANN + u = children.get(u & (1<>= childrenBitsLo + hi = u & (1<>= childrenBitsHi + switch u & (1<>= childrenBitsNodeType + wildcard = u&(1<>= nodesBitsTextLength + offset := x & (1<= 1 { + eax71, _, _, edx71 := cpuid(7, 1) + if X86.HasAVX512 { + X86.HasAVX512BF16 = isSet(5, eax71) + } + if X86.HasAVX { + X86.HasAVXIFMA = isSet(23, eax71) + X86.HasAVXVNNI = isSet(4, eax71) + X86.HasAVXVNNIInt8 = isSet(4, edx71) + } + } } func isSet(bitpos uint, value uint32) bool { diff --git a/vendor/golang.org/x/sys/unix/auxv.go b/vendor/golang.org/x/sys/unix/auxv.go new file mode 100644 index 000000000..37a82528f --- /dev/null +++ b/vendor/golang.org/x/sys/unix/auxv.go @@ -0,0 +1,36 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.21 && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos) + +package unix + +import ( + "syscall" + "unsafe" +) + +//go:linkname runtime_getAuxv runtime.getAuxv +func runtime_getAuxv() []uintptr + +// Auxv returns the ELF auxiliary vector as a sequence of key/value pairs. +// The returned slice is always a fresh copy, owned by the caller. +// It returns an error on non-ELF platforms, or if the auxiliary vector cannot be accessed, +// which happens in some locked-down environments and build modes. +func Auxv() ([][2]uintptr, error) { + vec := runtime_getAuxv() + vecLen := len(vec) + + if vecLen == 0 { + return nil, syscall.ENOENT + } + + if vecLen%2 != 0 { + return nil, syscall.EINVAL + } + + result := make([]uintptr, vecLen) + copy(result, vec) + return unsafe.Slice((*[2]uintptr)(unsafe.Pointer(&result[0])), vecLen/2), nil +} diff --git a/vendor/golang.org/x/sys/unix/auxv_unsupported.go b/vendor/golang.org/x/sys/unix/auxv_unsupported.go new file mode 100644 index 000000000..1200487f2 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/auxv_unsupported.go @@ -0,0 +1,13 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !go1.21 && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos) + +package unix + +import "syscall" + +func Auxv() ([][2]uintptr, error) { + return nil, syscall.ENOTSUP +} diff --git a/vendor/golang.org/x/sys/unix/syscall_dragonfly.go b/vendor/golang.org/x/sys/unix/syscall_dragonfly.go index 97cb916f2..be8c00207 100644 --- a/vendor/golang.org/x/sys/unix/syscall_dragonfly.go +++ b/vendor/golang.org/x/sys/unix/syscall_dragonfly.go @@ -246,6 +246,18 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e return sendfile(outfd, infd, offset, count) } +func Dup3(oldfd, newfd, flags int) error { + if oldfd == newfd || flags&^O_CLOEXEC != 0 { + return EINVAL + } + how := F_DUP2FD + if flags&O_CLOEXEC != 0 { + how = F_DUP2FD_CLOEXEC + } + _, err := fcntl(oldfd, how, newfd) + return err +} + /* * Exposed directly */ diff --git a/vendor/golang.org/x/sys/unix/syscall_solaris.go b/vendor/golang.org/x/sys/unix/syscall_solaris.go index 21974af06..abc395547 100644 --- a/vendor/golang.org/x/sys/unix/syscall_solaris.go +++ b/vendor/golang.org/x/sys/unix/syscall_solaris.go @@ -1102,3 +1102,90 @@ func (s *Strioctl) SetInt(i int) { func IoctlSetStrioctlRetInt(fd int, req int, s *Strioctl) (int, error) { return ioctlPtrRet(fd, req, unsafe.Pointer(s)) } + +// Ucred Helpers +// See ucred(3c) and getpeerucred(3c) + +//sys getpeerucred(fd uintptr, ucred *uintptr) (err error) +//sys ucredFree(ucred uintptr) = ucred_free +//sys ucredGet(pid int) (ucred uintptr, err error) = ucred_get +//sys ucredGeteuid(ucred uintptr) (uid int) = ucred_geteuid +//sys ucredGetegid(ucred uintptr) (gid int) = ucred_getegid +//sys ucredGetruid(ucred uintptr) (uid int) = ucred_getruid +//sys ucredGetrgid(ucred uintptr) (gid int) = ucred_getrgid +//sys ucredGetsuid(ucred uintptr) (uid int) = ucred_getsuid +//sys ucredGetsgid(ucred uintptr) (gid int) = ucred_getsgid +//sys ucredGetpid(ucred uintptr) (pid int) = ucred_getpid + +// Ucred is an opaque struct that holds user credentials. +type Ucred struct { + ucred uintptr +} + +// We need to ensure that ucredFree is called on the underlying ucred +// when the Ucred is garbage collected. +func ucredFinalizer(u *Ucred) { + ucredFree(u.ucred) +} + +func GetPeerUcred(fd uintptr) (*Ucred, error) { + var ucred uintptr + err := getpeerucred(fd, &ucred) + if err != nil { + return nil, err + } + result := &Ucred{ + ucred: ucred, + } + // set the finalizer on the result so that the ucred will be freed + runtime.SetFinalizer(result, ucredFinalizer) + return result, nil +} + +func UcredGet(pid int) (*Ucred, error) { + ucred, err := ucredGet(pid) + if err != nil { + return nil, err + } + result := &Ucred{ + ucred: ucred, + } + // set the finalizer on the result so that the ucred will be freed + runtime.SetFinalizer(result, ucredFinalizer) + return result, nil +} + +func (u *Ucred) Geteuid() int { + defer runtime.KeepAlive(u) + return ucredGeteuid(u.ucred) +} + +func (u *Ucred) Getruid() int { + defer runtime.KeepAlive(u) + return ucredGetruid(u.ucred) +} + +func (u *Ucred) Getsuid() int { + defer runtime.KeepAlive(u) + return ucredGetsuid(u.ucred) +} + +func (u *Ucred) Getegid() int { + defer runtime.KeepAlive(u) + return ucredGetegid(u.ucred) +} + +func (u *Ucred) Getrgid() int { + defer runtime.KeepAlive(u) + return ucredGetrgid(u.ucred) +} + +func (u *Ucred) Getsgid() int { + defer runtime.KeepAlive(u) + return ucredGetsgid(u.ucred) +} + +func (u *Ucred) Getpid() int { + defer runtime.KeepAlive(u) + return ucredGetpid(u.ucred) +} diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go index 6ebc48b3f..4f432bfe8 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -1245,6 +1245,7 @@ const ( FAN_REPORT_DFID_NAME = 0xc00 FAN_REPORT_DFID_NAME_TARGET = 0x1e00 FAN_REPORT_DIR_FID = 0x400 + FAN_REPORT_FD_ERROR = 0x2000 FAN_REPORT_FID = 0x200 FAN_REPORT_NAME = 0x800 FAN_REPORT_PIDFD = 0x80 @@ -1330,8 +1331,10 @@ const ( FUSE_SUPER_MAGIC = 0x65735546 FUTEXFS_SUPER_MAGIC = 0xbad1dea F_ADD_SEALS = 0x409 + F_CREATED_QUERY = 0x404 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 + F_DUPFD_QUERY = 0x403 F_EXLCK = 0x4 F_GETFD = 0x1 F_GETFL = 0x3 @@ -1551,6 +1554,7 @@ const ( IPPROTO_ROUTING = 0x2b IPPROTO_RSVP = 0x2e IPPROTO_SCTP = 0x84 + IPPROTO_SMC = 0x100 IPPROTO_TCP = 0x6 IPPROTO_TP = 0x1d IPPROTO_UDP = 0x11 @@ -1623,6 +1627,8 @@ const ( IPV6_UNICAST_IF = 0x4c IPV6_USER_FLOW = 0xe IPV6_V6ONLY = 0x1a + IPV6_VERSION = 0x60 + IPV6_VERSION_MASK = 0xf0 IPV6_XFRM_POLICY = 0x23 IP_ADD_MEMBERSHIP = 0x23 IP_ADD_SOURCE_MEMBERSHIP = 0x27 @@ -1867,6 +1873,7 @@ const ( MADV_UNMERGEABLE = 0xd MADV_WILLNEED = 0x3 MADV_WIPEONFORK = 0x12 + MAP_DROPPABLE = 0x8 MAP_FILE = 0x0 MAP_FIXED = 0x10 MAP_FIXED_NOREPLACE = 0x100000 @@ -1967,6 +1974,7 @@ const ( MSG_PEEK = 0x2 MSG_PROXY = 0x10 MSG_RST = 0x1000 + MSG_SOCK_DEVMEM = 0x2000000 MSG_SYN = 0x400 MSG_TRUNC = 0x20 MSG_TRYHARD = 0x4 @@ -2083,6 +2091,7 @@ const ( NFC_ATR_REQ_MAXSIZE = 0x40 NFC_ATR_RES_GB_MAXSIZE = 0x2f NFC_ATR_RES_MAXSIZE = 0x40 + NFC_ATS_MAXSIZE = 0x14 NFC_COMM_ACTIVE = 0x0 NFC_COMM_PASSIVE = 0x1 NFC_DEVICE_NAME_MAXSIZE = 0x8 @@ -2163,6 +2172,7 @@ const ( NFNL_SUBSYS_QUEUE = 0x3 NFNL_SUBSYS_ULOG = 0x4 NFS_SUPER_MAGIC = 0x6969 + NFT_BITWISE_BOOL = 0x0 NFT_CHAIN_FLAGS = 0x7 NFT_CHAIN_MAXNAMELEN = 0x100 NFT_CT_MAX = 0x17 @@ -2491,6 +2501,7 @@ const ( PR_GET_PDEATHSIG = 0x2 PR_GET_SECCOMP = 0x15 PR_GET_SECUREBITS = 0x1b + PR_GET_SHADOW_STACK_STATUS = 0x4a PR_GET_SPECULATION_CTRL = 0x34 PR_GET_TAGGED_ADDR_CTRL = 0x38 PR_GET_THP_DISABLE = 0x2a @@ -2499,6 +2510,7 @@ const ( PR_GET_TIMING = 0xd PR_GET_TSC = 0x19 PR_GET_UNALIGN = 0x5 + PR_LOCK_SHADOW_STACK_STATUS = 0x4c PR_MCE_KILL = 0x21 PR_MCE_KILL_CLEAR = 0x0 PR_MCE_KILL_DEFAULT = 0x2 @@ -2525,6 +2537,8 @@ const ( PR_PAC_GET_ENABLED_KEYS = 0x3d PR_PAC_RESET_KEYS = 0x36 PR_PAC_SET_ENABLED_KEYS = 0x3c + PR_PMLEN_MASK = 0x7f000000 + PR_PMLEN_SHIFT = 0x18 PR_PPC_DEXCR_CTRL_CLEAR = 0x4 PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC = 0x10 PR_PPC_DEXCR_CTRL_EDITABLE = 0x1 @@ -2592,6 +2606,7 @@ const ( PR_SET_PTRACER = 0x59616d61 PR_SET_SECCOMP = 0x16 PR_SET_SECUREBITS = 0x1c + PR_SET_SHADOW_STACK_STATUS = 0x4b PR_SET_SPECULATION_CTRL = 0x35 PR_SET_SYSCALL_USER_DISPATCH = 0x3b PR_SET_TAGGED_ADDR_CTRL = 0x37 @@ -2602,6 +2617,9 @@ const ( PR_SET_UNALIGN = 0x6 PR_SET_VMA = 0x53564d41 PR_SET_VMA_ANON_NAME = 0x0 + PR_SHADOW_STACK_ENABLE = 0x1 + PR_SHADOW_STACK_PUSH = 0x4 + PR_SHADOW_STACK_WRITE = 0x2 PR_SME_GET_VL = 0x40 PR_SME_SET_VL = 0x3f PR_SME_SET_VL_ONEXEC = 0x40000 @@ -2911,7 +2929,6 @@ const ( RTM_NEWNEXTHOP = 0x68 RTM_NEWNEXTHOPBUCKET = 0x74 RTM_NEWNSID = 0x58 - RTM_NEWNVLAN = 0x70 RTM_NEWPREFIX = 0x34 RTM_NEWQDISC = 0x24 RTM_NEWROUTE = 0x18 @@ -2920,6 +2937,7 @@ const ( RTM_NEWTCLASS = 0x28 RTM_NEWTFILTER = 0x2c RTM_NEWTUNNEL = 0x78 + RTM_NEWVLAN = 0x70 RTM_NR_FAMILIES = 0x1b RTM_NR_MSGTYPES = 0x6c RTM_SETDCB = 0x4f diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go index c0d45e320..75207613c 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go @@ -116,6 +116,8 @@ const ( IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -304,6 +306,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go index c731d24f0..c68acda53 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go @@ -116,6 +116,8 @@ const ( IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -305,6 +307,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go index 680018a4a..a8c607ab8 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go @@ -115,6 +115,8 @@ const ( IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -310,6 +312,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go index a63909f30..18563dd8d 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go @@ -109,6 +109,7 @@ const ( F_SETOWN = 0x8 F_UNLCK = 0x2 F_WRLCK = 0x1 + GCS_MAGIC = 0x47435300 HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 @@ -119,6 +120,8 @@ const ( IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -302,6 +305,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go index 9b0a2573f..22912cdaa 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go @@ -116,6 +116,8 @@ const ( IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -297,6 +299,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go index 958e6e064..29344eb37 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go @@ -115,6 +115,8 @@ const ( IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x80 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 + IPV6_FLOWINFO_MASK = 0xfffffff + IPV6_FLOWLABEL_MASK = 0xfffff ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -303,6 +305,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go index 50c7f25bd..20d51fb96 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go @@ -115,6 +115,8 @@ const ( IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x80 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 + IPV6_FLOWINFO_MASK = 0xfffffff + IPV6_FLOWLABEL_MASK = 0xfffff ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -303,6 +305,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go index ced21d66d..321b60902 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go @@ -115,6 +115,8 @@ const ( IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x80 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -303,6 +305,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go index 226c04419..9bacdf1e2 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go @@ -115,6 +115,8 @@ const ( IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x80 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -303,6 +305,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go index 3122737cd..c22427261 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go @@ -115,6 +115,8 @@ const ( IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 + IPV6_FLOWINFO_MASK = 0xfffffff + IPV6_FLOWLABEL_MASK = 0xfffff ISIG = 0x80 IUCLC = 0x1000 IXOFF = 0x400 @@ -358,6 +360,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go index eb5d3467e..6270c8ee1 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go @@ -115,6 +115,8 @@ const ( IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 + IPV6_FLOWINFO_MASK = 0xfffffff + IPV6_FLOWLABEL_MASK = 0xfffff ISIG = 0x80 IUCLC = 0x1000 IXOFF = 0x400 @@ -362,6 +364,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go index e921ebc60..9966c1941 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go @@ -115,6 +115,8 @@ const ( IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 ISIG = 0x80 IUCLC = 0x1000 IXOFF = 0x400 @@ -362,6 +364,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go index 38ba81c55..848e5fcc4 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go @@ -115,6 +115,8 @@ const ( IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -294,6 +296,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go index 71f040097..669b2adb8 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go @@ -115,6 +115,8 @@ const ( IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 + IPV6_FLOWINFO_MASK = 0xfffffff + IPV6_FLOWLABEL_MASK = 0xfffff ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -366,6 +368,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go index c44a31332..4834e5751 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go @@ -119,6 +119,8 @@ const ( IN_CLOEXEC = 0x400000 IN_NONBLOCK = 0x4000 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 + IPV6_FLOWINFO_MASK = 0xfffffff + IPV6_FLOWLABEL_MASK = 0xfffff ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -357,6 +359,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x38 SCM_TIMESTAMPING_PKTINFO = 0x3c SCM_TIMESTAMPNS = 0x21 + SCM_TS_OPT_ID = 0x5a SCM_TXTIME = 0x3f SCM_WIFI_STATUS = 0x25 SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go index 829b87feb..c6545413c 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go @@ -141,6 +141,16 @@ import ( //go:cgo_import_dynamic libc_getpeername getpeername "libsocket.so" //go:cgo_import_dynamic libc_setsockopt setsockopt "libsocket.so" //go:cgo_import_dynamic libc_recvfrom recvfrom "libsocket.so" +//go:cgo_import_dynamic libc_getpeerucred getpeerucred "libc.so" +//go:cgo_import_dynamic libc_ucred_get ucred_get "libc.so" +//go:cgo_import_dynamic libc_ucred_geteuid ucred_geteuid "libc.so" +//go:cgo_import_dynamic libc_ucred_getegid ucred_getegid "libc.so" +//go:cgo_import_dynamic libc_ucred_getruid ucred_getruid "libc.so" +//go:cgo_import_dynamic libc_ucred_getrgid ucred_getrgid "libc.so" +//go:cgo_import_dynamic libc_ucred_getsuid ucred_getsuid "libc.so" +//go:cgo_import_dynamic libc_ucred_getsgid ucred_getsgid "libc.so" +//go:cgo_import_dynamic libc_ucred_getpid ucred_getpid "libc.so" +//go:cgo_import_dynamic libc_ucred_free ucred_free "libc.so" //go:cgo_import_dynamic libc_port_create port_create "libc.so" //go:cgo_import_dynamic libc_port_associate port_associate "libc.so" //go:cgo_import_dynamic libc_port_dissociate port_dissociate "libc.so" @@ -280,6 +290,16 @@ import ( //go:linkname procgetpeername libc_getpeername //go:linkname procsetsockopt libc_setsockopt //go:linkname procrecvfrom libc_recvfrom +//go:linkname procgetpeerucred libc_getpeerucred +//go:linkname procucred_get libc_ucred_get +//go:linkname procucred_geteuid libc_ucred_geteuid +//go:linkname procucred_getegid libc_ucred_getegid +//go:linkname procucred_getruid libc_ucred_getruid +//go:linkname procucred_getrgid libc_ucred_getrgid +//go:linkname procucred_getsuid libc_ucred_getsuid +//go:linkname procucred_getsgid libc_ucred_getsgid +//go:linkname procucred_getpid libc_ucred_getpid +//go:linkname procucred_free libc_ucred_free //go:linkname procport_create libc_port_create //go:linkname procport_associate libc_port_associate //go:linkname procport_dissociate libc_port_dissociate @@ -420,6 +440,16 @@ var ( procgetpeername, procsetsockopt, procrecvfrom, + procgetpeerucred, + procucred_get, + procucred_geteuid, + procucred_getegid, + procucred_getruid, + procucred_getrgid, + procucred_getsuid, + procucred_getsgid, + procucred_getpid, + procucred_free, procport_create, procport_associate, procport_dissociate, @@ -2029,6 +2059,90 @@ func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Sockl // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func getpeerucred(fd uintptr, ucred *uintptr) (err error) { + _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procgetpeerucred)), 2, uintptr(fd), uintptr(unsafe.Pointer(ucred)), 0, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ucredGet(pid int) (ucred uintptr, err error) { + r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procucred_get)), 1, uintptr(pid), 0, 0, 0, 0, 0) + ucred = uintptr(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ucredGeteuid(ucred uintptr) (uid int) { + r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_geteuid)), 1, uintptr(ucred), 0, 0, 0, 0, 0) + uid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ucredGetegid(ucred uintptr) (gid int) { + r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getegid)), 1, uintptr(ucred), 0, 0, 0, 0, 0) + gid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ucredGetruid(ucred uintptr) (uid int) { + r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getruid)), 1, uintptr(ucred), 0, 0, 0, 0, 0) + uid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ucredGetrgid(ucred uintptr) (gid int) { + r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getrgid)), 1, uintptr(ucred), 0, 0, 0, 0, 0) + gid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ucredGetsuid(ucred uintptr) (uid int) { + r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getsuid)), 1, uintptr(ucred), 0, 0, 0, 0, 0) + uid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ucredGetsgid(ucred uintptr) (gid int) { + r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getsgid)), 1, uintptr(ucred), 0, 0, 0, 0, 0) + gid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ucredGetpid(ucred uintptr) (pid int) { + r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getpid)), 1, uintptr(ucred), 0, 0, 0, 0, 0) + pid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ucredFree(ucred uintptr) { + sysvicall6(uintptr(unsafe.Pointer(&procucred_free)), 1, uintptr(ucred), 0, 0, 0, 0, 0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func port_create() (n int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procport_create)), 0, 0, 0, 0, 0, 0, 0) n = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go index 524b0820c..c79aaff30 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go @@ -458,4 +458,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go index f485dbf45..5eb450695 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go @@ -381,4 +381,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go index 70b35bf3b..05e502974 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go @@ -422,4 +422,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go index 1893e2fe8..38c53ec51 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go @@ -325,4 +325,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go index 16a4017da..31d2e71a1 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go @@ -321,4 +321,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go index 7e567f1ef..f4184a336 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go @@ -442,4 +442,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 4460 SYS_LSM_LIST_MODULES = 4461 SYS_MSEAL = 4462 + SYS_SETXATTRAT = 4463 + SYS_GETXATTRAT = 4464 + SYS_LISTXATTRAT = 4465 + SYS_REMOVEXATTRAT = 4466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go index 38ae55e5e..05b996227 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go @@ -372,4 +372,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 5460 SYS_LSM_LIST_MODULES = 5461 SYS_MSEAL = 5462 + SYS_SETXATTRAT = 5463 + SYS_GETXATTRAT = 5464 + SYS_LISTXATTRAT = 5465 + SYS_REMOVEXATTRAT = 5466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go index 55e92e60a..43a256e9e 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go @@ -372,4 +372,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 5460 SYS_LSM_LIST_MODULES = 5461 SYS_MSEAL = 5462 + SYS_SETXATTRAT = 5463 + SYS_GETXATTRAT = 5464 + SYS_LISTXATTRAT = 5465 + SYS_REMOVEXATTRAT = 5466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go index 60658d6a0..eea5ddfc2 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go @@ -442,4 +442,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 4460 SYS_LSM_LIST_MODULES = 4461 SYS_MSEAL = 4462 + SYS_SETXATTRAT = 4463 + SYS_GETXATTRAT = 4464 + SYS_LISTXATTRAT = 4465 + SYS_REMOVEXATTRAT = 4466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go index e203e8a7e..0d777bfbb 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go @@ -449,4 +449,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go index 5944b97d5..b44636502 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go @@ -421,4 +421,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go index c66d416da..0c7d21c18 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go @@ -421,4 +421,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go index a5459e766..840539169 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go @@ -326,4 +326,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go index 01d86825b..fcf1b790d 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go @@ -387,4 +387,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go index 7b703e77c..52d15b5f9 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go @@ -400,4 +400,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index 5537148dc..a46abe647 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -4747,7 +4747,7 @@ const ( NL80211_ATTR_MAC_HINT = 0xc8 NL80211_ATTR_MAC_MASK = 0xd7 NL80211_ATTR_MAX_AP_ASSOC_STA = 0xca - NL80211_ATTR_MAX = 0x14c + NL80211_ATTR_MAX = 0x14d NL80211_ATTR_MAX_CRIT_PROT_DURATION = 0xb4 NL80211_ATTR_MAX_CSA_COUNTERS = 0xce NL80211_ATTR_MAX_MATCH_SETS = 0x85 @@ -5519,7 +5519,7 @@ const ( NL80211_MNTR_FLAG_CONTROL = 0x3 NL80211_MNTR_FLAG_COOK_FRAMES = 0x5 NL80211_MNTR_FLAG_FCSFAIL = 0x1 - NL80211_MNTR_FLAG_MAX = 0x6 + NL80211_MNTR_FLAG_MAX = 0x7 NL80211_MNTR_FLAG_OTHER_BSS = 0x4 NL80211_MNTR_FLAG_PLCPFAIL = 0x2 NL80211_MPATH_FLAG_ACTIVE = 0x1 @@ -6174,3 +6174,5 @@ type SockDiagReq struct { Family uint8 Protocol uint8 } + +const RTM_NEWNVLAN = 0x70 diff --git a/vendor/golang.org/x/sys/windows/dll_windows.go b/vendor/golang.org/x/sys/windows/dll_windows.go index 4e613cf63..3ca814f54 100644 --- a/vendor/golang.org/x/sys/windows/dll_windows.go +++ b/vendor/golang.org/x/sys/windows/dll_windows.go @@ -43,8 +43,8 @@ type DLL struct { // LoadDLL loads DLL file into memory. // // Warning: using LoadDLL without an absolute path name is subject to -// DLL preloading attacks. To safely load a system DLL, use LazyDLL -// with System set to true, or use LoadLibraryEx directly. +// DLL preloading attacks. To safely load a system DLL, use [NewLazySystemDLL], +// or use [LoadLibraryEx] directly. func LoadDLL(name string) (dll *DLL, err error) { namep, err := UTF16PtrFromString(name) if err != nil { @@ -271,6 +271,9 @@ func (d *LazyDLL) NewProc(name string) *LazyProc { } // NewLazyDLL creates new LazyDLL associated with DLL file. +// +// Warning: using NewLazyDLL without an absolute path name is subject to +// DLL preloading attacks. To safely load a system DLL, use [NewLazySystemDLL]. func NewLazyDLL(name string) *LazyDLL { return &LazyDLL{Name: name} } @@ -410,7 +413,3 @@ func loadLibraryEx(name string, system bool) (*DLL, error) { } return &DLL{Name: name, Handle: h}, nil } - -type errString string - -func (s errString) Error() string { return string(s) } diff --git a/vendor/modules.txt b/vendor/modules.txt index 3b7453f8a..f49cdcf33 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -315,7 +315,7 @@ github.com/zclconf/go-cty/cty/function/stdlib github.com/zclconf/go-cty/cty/gocty github.com/zclconf/go-cty/cty/json github.com/zclconf/go-cty/cty/set -# golang.org/x/crypto v0.31.0 +# golang.org/x/crypto v0.33.0 ## explicit; go 1.20 golang.org/x/crypto/argon2 golang.org/x/crypto/blake2b @@ -339,28 +339,30 @@ golang.org/x/mod/internal/lazyregexp golang.org/x/mod/modfile golang.org/x/mod/module golang.org/x/mod/semver -# golang.org/x/net v0.33.0 +# golang.org/x/net v0.35.0 ## explicit; go 1.18 golang.org/x/net/http/httpguts golang.org/x/net/http2 golang.org/x/net/http2/hpack golang.org/x/net/idna +golang.org/x/net/internal/httpcommon golang.org/x/net/internal/timeseries +golang.org/x/net/publicsuffix golang.org/x/net/trace # golang.org/x/oauth2 v0.22.0 ## explicit; go 1.18 golang.org/x/oauth2 golang.org/x/oauth2/clientcredentials golang.org/x/oauth2/internal -# golang.org/x/sync v0.10.0 +# golang.org/x/sync v0.11.0 ## explicit; go 1.18 golang.org/x/sync/errgroup -# golang.org/x/sys v0.28.0 +# golang.org/x/sys v0.30.0 ## explicit; go 1.18 golang.org/x/sys/cpu golang.org/x/sys/unix golang.org/x/sys/windows -# golang.org/x/text v0.21.0 +# golang.org/x/text v0.22.0 ## explicit; go 1.18 golang.org/x/text/secure/bidirule golang.org/x/text/transform diff --git a/website/docs/r/domain_name.html.markdown b/website/docs/r/domain_name.html.markdown new file mode 100644 index 000000000..6d5f4b443 --- /dev/null +++ b/website/docs/r/domain_name.html.markdown @@ -0,0 +1,230 @@ +--- +subcategory : "Domain names" +--- + +# ovh_domain_name + +Create and manage a domain name. + +## Important + +-> __NOTE__ To order a product through Terraform, your account needs to have a default payment method defined. This can be done in the [OVHcloud Control Panel](https://www.ovh.com/manager/#/dedicated/billing/payment/method) or via API with the [/me/payment/method](https://api.ovh.com/console/#/me/payment/method~GET) endpoint. + +~> __WARNING__ `BANK_ACCOUNT` is not supported anymore, please update your default payment method to `SEPA_DIRECT_DEBIT` + +## Example Usage + +```hcl +resource "ovh_domain_name" "domain" { + domain_name = "example.com" + + target_spec = { + dns_configuration = { + name_servers = [ + { + name_server = "dns101.ovh.net" + }, + { + name_server = "ns101.ovh.net" + } + ] + } + } +} +``` + +## Schema + +### Required + +- `domain_name` (String) Domain name + +### Optional + +- `checksum` (String) Computed hash used to control concurrent modification requests. Here, it represents the current target specification value +- `ovh_subsidiary` (String) OVH subsidiaries +- `plan` (Attributes List) (see [below for nested schema](#nestedatt--plan)) +- `plan_option` (Attributes List) (see [below for nested schema](#nestedatt--plan_option)) +- `target_spec` (Attributes) Latest target specification of the domain name resource. (see [below for nested schema](#nestedatt--target_spec)) + +### Read-Only + +- `current_state` (Attributes) Current state of the domain name (see [below for nested schema](#nestedatt--current_state)) +- `current_tasks` (Attributes List) Ongoing asynchronous tasks related to the domain name resource (see [below for nested schema](#nestedatt--current_tasks)) +- `iam` (Attributes) IAM resource metadata (see [below for nested schema](#nestedatt--iam)) +- `id` (String) Unique identifier for the resource. Here, the domain name itself is used as an identifier +- `order` (Attributes) Details about an Order (see [below for nested schema](#nestedatt--order)) +- `resource_status` (String) Reflects the readiness of the domain name resource. A new target specification request will be accepted only in `READY`, `UPDATING` or `ERROR` status + + +### Nested Schema for `plan` + +Required: + +- `duration` (String) Duration selected for the purchase of the product (defaults to "P1Y") +- `plan_code` (String) Identifier of the option offer +- `pricing_mode` (String) Pricing mode selected for the purchase of the product + +Optional: + +- `configuration` (Attributes List) (see [below for nested schema](#nestedatt--plan--configuration)) +- `item_id` (Number) Cart item to be linked +- `quantity` (Number) Quantity of product desired + + +### Nested Schema for `plan.configuration` + +Required: + +- `label` (String) Label for your configuration item +- `value` (String) Value or resource URL on API.OVH.COM of your configuration item + + + + +### Nested Schema for `plan_option` + +Required: + +- `duration` (String) Duration selected for the purchase of the product +- `plan_code` (String) Identifier of the option offer +- `pricing_mode` (String) Pricing mode selected for the purchase of the product +- `quantity` (Number) Quantity of product desired + +Optional: + +- `configuration` (Attributes List) (see [below for nested schema](#nestedatt--plan_option--configuration)) + + +### Nested Schema for `plan_option.configuration` + +Required: + +- `label` (String) Label for your configuration item +- `value` (String) Value or resource URL on API.OVH.COM of your configuration item + + + + +### Nested Schema for `target_spec` + +Optional: + +- `dns_configuration` (Attributes) The domain DNS configuration (see [below for nested schema](#nestedatt--target_spec--dns_configuration)) + + +### Nested Schema for `target_spec.dns_configuration` + +Optional: + +- `name_servers` (Attributes List) The name servers to update (see [below for nested schema](#nestedatt--target_spec--dns_configuration--name_servers)) + + +### Nested Schema for `target_spec.dns_configuration.name_servers` + +Optional: + +- `ipv4` (String) The IPv4 associated to the name server +- `ipv6` (String) The IPv6 associated to the name server +- `name_server` (String) The host name + + +### Nested Schema for `current_state` + +Read-Only: + +- `additional_states` (List of String) Domain additional states +- `dns_configuration` (Attributes) The domain DNS configuration (see [below for nested schema](#nestedatt--current_state--dns_configuration)) +- `extension` (String) Extension of the domain name +- `main_state` (String) Domain main state +- `name` (String) Domain name +- `protection_state` (String) Domain protection state +- `suspension_state` (String) Domain suspension state + + +### Nested Schema for `current_state.dns_configuration` + +Read-Only: + +- `configuration_type` (String) The type of DNS configuration of the domain +- `glue_record_ipv6supported` (Boolean) Whether the registry supports IPv6 or not +- `host_supported` (Boolean) Whether the registry accepts hosts or not +- `max_dns` (Number) The maximum number of name servers allowed by the registry +- `min_dns` (Number) The minimum number of name servers allowed by the registry +- `name_servers` (Attributes List) The name servers used by the domain name (see [below for nested schema](#nestedatt--current_state--dns_configuration--name_servers)) + + +### Nested Schema for `current_state.dns_configuration.name_servers` + +Read-Only: + +- `ipv4` (String) The IPv4 associated to the name server +- `ipv6` (String) The IPv6 associated to the name server +- `name_server` (String) The host name +- `name_server_type` (String) The type of name server + + +### Nested Schema for `current_tasks` + +Read-Only: + +- `id` (String) Identifier of the current task +- `link` (String) Link to the task details +- `status` (String) Current global status of the current task +- `type` (String) Type of the current task + + + +### Nested Schema for `iam` + +Read-Only: + +- `display_name` (String) Resource display name +- `id` (String) Unique identifier of the resource +- `tags` (Map of String) Resource tags. Tags that were internally computed are prefixed with ovh: +- `urn` (String) Unique resource name used in policies + + + +### Nested Schema for `order` + +Read-Only: + +- `date` (String) +- `details` (Attributes List) (see [below for nested schema](#nestedatt--order--details)) +- `expiration_date` (String) +- `order_id` (Number) + + +### Nested Schema for `order.details` + +Read-Only: + +- `description` (String) +- `detail_type` (String) Product type of item in order +- `domain` (String) +- `order_detail_id` (Number) +- `quantity` (String) + +## Import + +A domain name can be imported using its `domain_name`. + +Using the following configuration: + +```hcl +import { + to = ovh_domain_name.domain + id = "" +} +``` + +You can then run: + +```bash +$ terraform plan -generate-config-out=domain.tf +$ terraform apply +``` + +The file `domain.tf` will then contain the imported resource's configuration, that can be copied next to the `import` block above. +See https://developer.hashicorp.com/terraform/language/import/generating-configuration for more details. \ No newline at end of file