diff --git a/ovh/data_cloud_project_rancher_plan.go b/ovh/data_cloud_project_rancher_plan.go new file mode 100644 index 000000000..14eddcd14 --- /dev/null +++ b/ovh/data_cloud_project_rancher_plan.go @@ -0,0 +1,68 @@ +package ovh + +import ( + "context" + "fmt" + "net/url" + + "github.com/hashicorp/terraform-plugin-framework/datasource" +) + +var _ datasource.DataSourceWithConfigure = (*cloudProjectRancherPlanDataSource)(nil) + +func NewCloudProjectRancherPlanDataSource() datasource.DataSource { + return &cloudProjectRancherPlanDataSource{} +} + +type cloudProjectRancherPlanDataSource struct { + config *Config +} + +func (d *cloudProjectRancherPlanDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_cloud_project_rancher_plan" +} + +func (d *cloudProjectRancherPlanDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + + config, ok := req.ProviderData.(*Config) + if !ok { + resp.Diagnostics.AddError( + "Unexpected Data Source Configure Type", + fmt.Sprintf("Expected *Config, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + return + } + + d.config = config +} + +func (d *cloudProjectRancherPlanDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = CloudProjectRancherPlanDataSourceSchema(ctx) +} + +func (d *cloudProjectRancherPlanDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var data CloudProjectRancherPlanModel + + // Read Terraform configuration data into the model + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + + if resp.Diagnostics.HasError() { + return + } + + // Read API call logic + endpoint := "/v2/publicCloud/project/" + url.PathEscape(data.ProjectId.ValueString()) + "/reference/rancher/plan" + if err := d.config.OVHClient.Get(endpoint, &data.Plans); err != nil { + resp.Diagnostics.AddError( + fmt.Sprintf("Error calling Get %s", endpoint), + err.Error(), + ) + return + } + + // Save data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} diff --git a/ovh/data_cloud_project_rancher_plan_gen.go b/ovh/data_cloud_project_rancher_plan_gen.go new file mode 100644 index 000000000..f3343d1c0 --- /dev/null +++ b/ovh/data_cloud_project_rancher_plan_gen.go @@ -0,0 +1,602 @@ +// Code generated by terraform-plugin-framework-generator DO NOT EDIT. + +package ovh + +import ( + "context" + "encoding/json" + "fmt" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "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" + "strings" + + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" +) + +func CloudProjectRancherPlanDataSourceSchema(ctx context.Context) schema.Schema { + attrs := map[string]schema.Attribute{ + "plans": schema.SetNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "cause": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Cause for an unavailability", + MarkdownDescription: "Cause for an unavailability", + }, + "message": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Human-readable description of the unavailability cause", + MarkdownDescription: "Human-readable description of the unavailability cause", + }, + "name": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Name of the plan", + MarkdownDescription: "Name of the plan", + }, + "status": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Status of the plan", + MarkdownDescription: "Status of the plan", + }, + }, + CustomType: CloudProjectRancherPlanType{ + ObjectType: types.ObjectType{ + AttrTypes: CloudProjectRancherPlanValue{}.AttributeTypes(ctx), + }, + }, + }, + CustomType: ovhtypes.NewTfListNestedType[CloudProjectRancherPlanValue](ctx), + Computed: true, + }, + "project_id": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Required: true, + Description: "Project ID", + MarkdownDescription: "Project ID", + }, + } + + return schema.Schema{ + Attributes: attrs, + } +} + +type CloudProjectRancherPlanModel struct { + Plans ovhtypes.TfListNestedValue[CloudProjectRancherPlanValue] `tfsdk:"plans" json:"plans"` + ProjectId ovhtypes.TfStringValue `tfsdk:"project_id" json:"projectId"` +} + +var _ basetypes.ObjectTypable = CloudProjectRancherPlanType{} + +type CloudProjectRancherPlanType struct { + basetypes.ObjectType +} + +func (t CloudProjectRancherPlanType) Equal(o attr.Type) bool { + other, ok := o.(CloudProjectRancherPlanType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t CloudProjectRancherPlanType) String() string { + return "CloudProjectRancherPlanType" +} + +func (t CloudProjectRancherPlanType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + causeAttribute, ok := attributes["cause"] + + if !ok { + diags.AddError( + "Attribute Missing", + `cause is missing from object`) + + return nil, diags + } + + causeVal, ok := causeAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`cause expected to be ovhtypes.TfStringValue, was: %T`, causeAttribute)) + } + + messageAttribute, ok := attributes["message"] + + if !ok { + diags.AddError( + "Attribute Missing", + `message is missing from object`) + + return nil, diags + } + + messageVal, ok := messageAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`message expected to be ovhtypes.TfStringValue, was: %T`, messageAttribute)) + } + + 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)) + } + + 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)) + } + + if diags.HasError() { + return nil, diags + } + + return CloudProjectRancherPlanValue{ + Cause: causeVal, + Message: messageVal, + Name: nameVal, + Status: statusVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewCloudProjectRancherPlanValueNull() CloudProjectRancherPlanValue { + return CloudProjectRancherPlanValue{ + state: attr.ValueStateNull, + } +} + +func NewCloudProjectRancherPlanValueUnknown() CloudProjectRancherPlanValue { + return CloudProjectRancherPlanValue{ + state: attr.ValueStateUnknown, + } +} + +func NewCloudProjectRancherPlanValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (CloudProjectRancherPlanValue, 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 CloudProjectRancherPlanValue Attribute Value", + "While creating a CloudProjectRancherPlanValue value, a missing attribute value was detected. "+ + "A CloudProjectRancherPlanValue 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("CloudProjectRancherPlanValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid CloudProjectRancherPlanValue Attribute Type", + "While creating a CloudProjectRancherPlanValue value, an invalid attribute value was detected. "+ + "A CloudProjectRancherPlanValue 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("CloudProjectRancherPlanValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("CloudProjectRancherPlanValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra CloudProjectRancherPlanValue Attribute Value", + "While creating a CloudProjectRancherPlanValue value, an extra attribute value was detected. "+ + "A CloudProjectRancherPlanValue 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 CloudProjectRancherPlanValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewCloudProjectRancherPlanValueUnknown(), diags + } + + causeAttribute, ok := attributes["cause"] + + if !ok { + diags.AddError( + "Attribute Missing", + `cause is missing from object`) + + return NewCloudProjectRancherPlanValueUnknown(), diags + } + + causeVal, ok := causeAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`cause expected to be ovhtypes.TfStringValue, was: %T`, causeAttribute)) + } + + messageAttribute, ok := attributes["message"] + + if !ok { + diags.AddError( + "Attribute Missing", + `message is missing from object`) + + return NewCloudProjectRancherPlanValueUnknown(), diags + } + + messageVal, ok := messageAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`message expected to be ovhtypes.TfStringValue, was: %T`, messageAttribute)) + } + + nameAttribute, ok := attributes["name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name is missing from object`) + + return NewCloudProjectRancherPlanValueUnknown(), diags + } + + nameVal, ok := nameAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name expected to be ovhtypes.TfStringValue, was: %T`, nameAttribute)) + } + + statusAttribute, ok := attributes["status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status is missing from object`) + + return NewCloudProjectRancherPlanValueUnknown(), diags + } + + statusVal, ok := statusAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status expected to be ovhtypes.TfStringValue, was: %T`, statusAttribute)) + } + + if diags.HasError() { + return NewCloudProjectRancherPlanValueUnknown(), diags + } + + return CloudProjectRancherPlanValue{ + Cause: causeVal, + Message: messageVal, + Name: nameVal, + Status: statusVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewCloudProjectRancherPlanValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) CloudProjectRancherPlanValue { + object, diags := NewCloudProjectRancherPlanValue(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("NewCloudProjectRancherPlanValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t CloudProjectRancherPlanType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewCloudProjectRancherPlanValueNull(), 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 NewCloudProjectRancherPlanValueUnknown(), nil + } + + if in.IsNull() { + return NewCloudProjectRancherPlanValueNull(), 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 NewCloudProjectRancherPlanValueMust(CloudProjectRancherPlanValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t CloudProjectRancherPlanType) ValueType(ctx context.Context) attr.Value { + return CloudProjectRancherPlanValue{} +} + +var _ basetypes.ObjectValuable = CloudProjectRancherPlanValue{} + +type CloudProjectRancherPlanValue struct { + Cause ovhtypes.TfStringValue `tfsdk:"cause" json:"cause"` + Message ovhtypes.TfStringValue `tfsdk:"message" json:"message"` + Name ovhtypes.TfStringValue `tfsdk:"name" json:"name"` + Status ovhtypes.TfStringValue `tfsdk:"status" json:"status"` + state attr.ValueState +} + +func (v *CloudProjectRancherPlanValue) UnmarshalJSON(data []byte) error { + type JsonCloudProjectRancherPlanValue CloudProjectRancherPlanValue + + var tmp JsonCloudProjectRancherPlanValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.Cause = tmp.Cause + v.Message = tmp.Message + v.Name = tmp.Name + v.Status = tmp.Status + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *CloudProjectRancherPlanValue) MergeWith(other *CloudProjectRancherPlanValue) { + + if (v.Cause.IsUnknown() || v.Cause.IsNull()) && !other.Cause.IsUnknown() { + v.Cause = other.Cause + } + + if (v.Message.IsUnknown() || v.Message.IsNull()) && !other.Message.IsUnknown() { + v.Message = other.Message + } + + if (v.Name.IsUnknown() || v.Name.IsNull()) && !other.Name.IsUnknown() { + v.Name = other.Name + } + + if (v.Status.IsUnknown() || v.Status.IsNull()) && !other.Status.IsUnknown() { + v.Status = other.Status + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v CloudProjectRancherPlanValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "cause": v.Cause, + "message": v.Message, + "name": v.Name, + "status": v.Status, + } +} +func (v CloudProjectRancherPlanValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 4) + + var val tftypes.Value + var err error + + attrTypes["cause"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["message"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["name"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["status"] = 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.Cause.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["cause"] = val + + val, err = v.Message.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["message"] = val + + val, err = v.Name.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["name"] = val + + val, err = v.Status.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["status"] = 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 CloudProjectRancherPlanValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v CloudProjectRancherPlanValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v CloudProjectRancherPlanValue) String() string { + return "CloudProjectRancherPlanValue" +} + +func (v CloudProjectRancherPlanValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "cause": ovhtypes.TfStringType{}, + "message": ovhtypes.TfStringType{}, + "name": ovhtypes.TfStringType{}, + "status": ovhtypes.TfStringType{}, + }, + map[string]attr.Value{ + "cause": v.Cause, + "message": v.Message, + "name": v.Name, + "status": v.Status, + }) + + return objVal, diags +} + +func (v CloudProjectRancherPlanValue) Equal(o attr.Value) bool { + other, ok := o.(CloudProjectRancherPlanValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Cause.Equal(other.Cause) { + return false + } + + if !v.Message.Equal(other.Message) { + return false + } + + if !v.Name.Equal(other.Name) { + return false + } + + if !v.Status.Equal(other.Status) { + return false + } + + return true +} + +func (v CloudProjectRancherPlanValue) Type(ctx context.Context) attr.Type { + return CloudProjectRancherPlanType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v CloudProjectRancherPlanValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "cause": ovhtypes.TfStringType{}, + "message": ovhtypes.TfStringType{}, + "name": ovhtypes.TfStringType{}, + "status": ovhtypes.TfStringType{}, + } +} diff --git a/ovh/data_cloud_project_rancher_plan_test.go b/ovh/data_cloud_project_rancher_plan_test.go new file mode 100644 index 000000000..aec478273 --- /dev/null +++ b/ovh/data_cloud_project_rancher_plan_test.go @@ -0,0 +1,31 @@ +package ovh + +import ( + "fmt" + "os" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func TestAccDataSourceCloudProjectRancherPlan_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheckCloud(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: fmt.Sprintf(` + data "ovh_cloud_project_rancher_plan" "plans" { + project_id = "%s" + } + `, os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST")), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.ovh_cloud_project_rancher_plan.plans", "project_id", os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST")), + resource.TestCheckResourceAttrSet("data.ovh_cloud_project_rancher_plan.plans", "plans.#"), + resource.TestCheckResourceAttrSet("data.ovh_cloud_project_rancher_plan.plans", "plans.0.name"), + resource.TestCheckResourceAttrSet("data.ovh_cloud_project_rancher_plan.plans", "plans.0.status"), + ), + }, + }, + }) +} diff --git a/ovh/data_cloud_project_rancher_version.go b/ovh/data_cloud_project_rancher_version.go new file mode 100644 index 000000000..c76a5885a --- /dev/null +++ b/ovh/data_cloud_project_rancher_version.go @@ -0,0 +1,68 @@ +package ovh + +import ( + "context" + "fmt" + "net/url" + + "github.com/hashicorp/terraform-plugin-framework/datasource" +) + +var _ datasource.DataSourceWithConfigure = (*cloudProjectRancherVersionDataSource)(nil) + +func NewCloudProjectRancherVersionDataSource() datasource.DataSource { + return &cloudProjectRancherVersionDataSource{} +} + +type cloudProjectRancherVersionDataSource struct { + config *Config +} + +func (d *cloudProjectRancherVersionDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_cloud_project_rancher_version" +} + +func (d *cloudProjectRancherVersionDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + + config, ok := req.ProviderData.(*Config) + if !ok { + resp.Diagnostics.AddError( + "Unexpected Data Source Configure Type", + fmt.Sprintf("Expected *Config, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + return + } + + d.config = config +} + +func (d *cloudProjectRancherVersionDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = CloudProjectRancherVersionDataSourceSchema(ctx) +} + +func (d *cloudProjectRancherVersionDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var data CloudProjectRancherVersionModel + + // Read Terraform configuration data into the model + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + + if resp.Diagnostics.HasError() { + return + } + + // Read API call logic + endpoint := "/v2/publicCloud/project/" + url.PathEscape(data.ProjectId.ValueString()) + "/reference/rancher/version" + if err := d.config.OVHClient.Get(endpoint, &data.Versions); err != nil { + resp.Diagnostics.AddError( + fmt.Sprintf("Error calling Get %s", endpoint), + err.Error(), + ) + return + } + + // Save data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} diff --git a/ovh/data_cloud_project_rancher_version_gen.go b/ovh/data_cloud_project_rancher_version_gen.go new file mode 100644 index 000000000..518344340 --- /dev/null +++ b/ovh/data_cloud_project_rancher_version_gen.go @@ -0,0 +1,669 @@ +// Code generated by terraform-plugin-framework-generator DO NOT EDIT. + +package ovh + +import ( + "context" + "encoding/json" + "fmt" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "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" + "strings" + + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" +) + +func CloudProjectRancherVersionDataSourceSchema(ctx context.Context) schema.Schema { + attrs := map[string]schema.Attribute{ + "versions": schema.SetNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "cause": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Cause for an unavailability", + MarkdownDescription: "Cause for an unavailability", + }, + "changelog_url": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Changelog URL of the version", + MarkdownDescription: "Changelog URL of the version", + }, + "message": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Human-readable description of the unavailability cause", + MarkdownDescription: "Human-readable description of the unavailability cause", + }, + "name": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Name of the version", + MarkdownDescription: "Name of the version", + }, + "status": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Status of the version", + MarkdownDescription: "Status of the version", + }, + }, + CustomType: CloudProjectRancherVersionType{ + ObjectType: types.ObjectType{ + AttrTypes: CloudProjectRancherVersionValue{}.AttributeTypes(ctx), + }, + }, + }, + CustomType: ovhtypes.NewTfListNestedType[CloudProjectRancherVersionValue](ctx), + Computed: true, + }, + "project_id": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Required: true, + Description: "Project ID", + MarkdownDescription: "Project ID", + }, + } + + return schema.Schema{ + Attributes: attrs, + } +} + +type CloudProjectRancherVersionModel struct { + Versions ovhtypes.TfListNestedValue[CloudProjectRancherVersionValue] `tfsdk:"versions" json:"versions"` + ProjectId ovhtypes.TfStringValue `tfsdk:"project_id" json:"projectId"` +} + +var _ basetypes.ObjectTypable = CloudProjectRancherVersionType{} + +type CloudProjectRancherVersionType struct { + basetypes.ObjectType +} + +func (t CloudProjectRancherVersionType) Equal(o attr.Type) bool { + other, ok := o.(CloudProjectRancherVersionType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t CloudProjectRancherVersionType) String() string { + return "CloudProjectRancherVersionType" +} + +func (t CloudProjectRancherVersionType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + causeAttribute, ok := attributes["cause"] + + if !ok { + diags.AddError( + "Attribute Missing", + `cause is missing from object`) + + return nil, diags + } + + causeVal, ok := causeAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`cause expected to be ovhtypes.TfStringValue, was: %T`, causeAttribute)) + } + + changelogUrlAttribute, ok := attributes["changelog_url"] + + if !ok { + diags.AddError( + "Attribute Missing", + `changelog_url is missing from object`) + + return nil, diags + } + + changelogUrlVal, ok := changelogUrlAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`changelog_url expected to be ovhtypes.TfStringValue, was: %T`, changelogUrlAttribute)) + } + + messageAttribute, ok := attributes["message"] + + if !ok { + diags.AddError( + "Attribute Missing", + `message is missing from object`) + + return nil, diags + } + + messageVal, ok := messageAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`message expected to be ovhtypes.TfStringValue, was: %T`, messageAttribute)) + } + + 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)) + } + + 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)) + } + + if diags.HasError() { + return nil, diags + } + + return CloudProjectRancherVersionValue{ + Cause: causeVal, + ChangelogUrl: changelogUrlVal, + Message: messageVal, + Name: nameVal, + Status: statusVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewCloudProjectRancherVersionValueNull() CloudProjectRancherVersionValue { + return CloudProjectRancherVersionValue{ + state: attr.ValueStateNull, + } +} + +func NewCloudProjectRancherVersionValueUnknown() CloudProjectRancherVersionValue { + return CloudProjectRancherVersionValue{ + state: attr.ValueStateUnknown, + } +} + +func NewCloudProjectRancherVersionValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (CloudProjectRancherVersionValue, 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 CloudProjectRancherVersionValue Attribute Value", + "While creating a CloudProjectRancherVersionValue value, a missing attribute value was detected. "+ + "A CloudProjectRancherVersionValue 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("CloudProjectRancherVersionValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid CloudProjectRancherVersionValue Attribute Type", + "While creating a CloudProjectRancherVersionValue value, an invalid attribute value was detected. "+ + "A CloudProjectRancherVersionValue 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("CloudProjectRancherVersionValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("CloudProjectRancherVersionValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra CloudProjectRancherVersionValue Attribute Value", + "While creating a CloudProjectRancherVersionValue value, an extra attribute value was detected. "+ + "A CloudProjectRancherVersionValue 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 CloudProjectRancherVersionValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewCloudProjectRancherVersionValueUnknown(), diags + } + + causeAttribute, ok := attributes["cause"] + + if !ok { + diags.AddError( + "Attribute Missing", + `cause is missing from object`) + + return NewCloudProjectRancherVersionValueUnknown(), diags + } + + causeVal, ok := causeAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`cause expected to be ovhtypes.TfStringValue, was: %T`, causeAttribute)) + } + + changelogUrlAttribute, ok := attributes["changelog_url"] + + if !ok { + diags.AddError( + "Attribute Missing", + `changelog_url is missing from object`) + + return NewCloudProjectRancherVersionValueUnknown(), diags + } + + changelogUrlVal, ok := changelogUrlAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`changelog_url expected to be ovhtypes.TfStringValue, was: %T`, changelogUrlAttribute)) + } + + messageAttribute, ok := attributes["message"] + + if !ok { + diags.AddError( + "Attribute Missing", + `message is missing from object`) + + return NewCloudProjectRancherVersionValueUnknown(), diags + } + + messageVal, ok := messageAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`message expected to be ovhtypes.TfStringValue, was: %T`, messageAttribute)) + } + + nameAttribute, ok := attributes["name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name is missing from object`) + + return NewCloudProjectRancherVersionValueUnknown(), diags + } + + nameVal, ok := nameAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name expected to be ovhtypes.TfStringValue, was: %T`, nameAttribute)) + } + + statusAttribute, ok := attributes["status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status is missing from object`) + + return NewCloudProjectRancherVersionValueUnknown(), diags + } + + statusVal, ok := statusAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status expected to be ovhtypes.TfStringValue, was: %T`, statusAttribute)) + } + + if diags.HasError() { + return NewCloudProjectRancherVersionValueUnknown(), diags + } + + return CloudProjectRancherVersionValue{ + Cause: causeVal, + ChangelogUrl: changelogUrlVal, + Message: messageVal, + Name: nameVal, + Status: statusVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewCloudProjectRancherVersionValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) CloudProjectRancherVersionValue { + object, diags := NewCloudProjectRancherVersionValue(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("NewCloudProjectRancherVersionValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t CloudProjectRancherVersionType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewCloudProjectRancherVersionValueNull(), 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 NewCloudProjectRancherVersionValueUnknown(), nil + } + + if in.IsNull() { + return NewCloudProjectRancherVersionValueNull(), 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 NewCloudProjectRancherVersionValueMust(CloudProjectRancherVersionValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t CloudProjectRancherVersionType) ValueType(ctx context.Context) attr.Value { + return CloudProjectRancherVersionValue{} +} + +var _ basetypes.ObjectValuable = CloudProjectRancherVersionValue{} + +type CloudProjectRancherVersionValue struct { + Cause ovhtypes.TfStringValue `tfsdk:"cause" json:"cause"` + ChangelogUrl ovhtypes.TfStringValue `tfsdk:"changelog_url" json:"changelogUrl"` + Message ovhtypes.TfStringValue `tfsdk:"message" json:"message"` + Name ovhtypes.TfStringValue `tfsdk:"name" json:"name"` + Status ovhtypes.TfStringValue `tfsdk:"status" json:"status"` + state attr.ValueState +} + +func (v *CloudProjectRancherVersionValue) UnmarshalJSON(data []byte) error { + type JsonCloudProjectRancherVersionValue CloudProjectRancherVersionValue + + var tmp JsonCloudProjectRancherVersionValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.Cause = tmp.Cause + v.ChangelogUrl = tmp.ChangelogUrl + v.Message = tmp.Message + v.Name = tmp.Name + v.Status = tmp.Status + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *CloudProjectRancherVersionValue) MergeWith(other *CloudProjectRancherVersionValue) { + + if (v.Cause.IsUnknown() || v.Cause.IsNull()) && !other.Cause.IsUnknown() { + v.Cause = other.Cause + } + + if (v.ChangelogUrl.IsUnknown() || v.ChangelogUrl.IsNull()) && !other.ChangelogUrl.IsUnknown() { + v.ChangelogUrl = other.ChangelogUrl + } + + if (v.Message.IsUnknown() || v.Message.IsNull()) && !other.Message.IsUnknown() { + v.Message = other.Message + } + + if (v.Name.IsUnknown() || v.Name.IsNull()) && !other.Name.IsUnknown() { + v.Name = other.Name + } + + if (v.Status.IsUnknown() || v.Status.IsNull()) && !other.Status.IsUnknown() { + v.Status = other.Status + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v CloudProjectRancherVersionValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "cause": v.Cause, + "changelogUrl": v.ChangelogUrl, + "message": v.Message, + "name": v.Name, + "status": v.Status, + } +} +func (v CloudProjectRancherVersionValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 5) + + var val tftypes.Value + var err error + + attrTypes["cause"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["changelog_url"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["message"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["name"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["status"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 5) + + val, err = v.Cause.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["cause"] = val + + val, err = v.ChangelogUrl.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["changelog_url"] = val + + val, err = v.Message.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["message"] = val + + val, err = v.Name.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["name"] = val + + val, err = v.Status.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["status"] = 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 CloudProjectRancherVersionValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v CloudProjectRancherVersionValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v CloudProjectRancherVersionValue) String() string { + return "CloudProjectRancherVersionValue" +} + +func (v CloudProjectRancherVersionValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "cause": ovhtypes.TfStringType{}, + "changelog_url": ovhtypes.TfStringType{}, + "message": ovhtypes.TfStringType{}, + "name": ovhtypes.TfStringType{}, + "status": ovhtypes.TfStringType{}, + }, + map[string]attr.Value{ + "cause": v.Cause, + "changelog_url": v.ChangelogUrl, + "message": v.Message, + "name": v.Name, + "status": v.Status, + }) + + return objVal, diags +} + +func (v CloudProjectRancherVersionValue) Equal(o attr.Value) bool { + other, ok := o.(CloudProjectRancherVersionValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Cause.Equal(other.Cause) { + return false + } + + if !v.ChangelogUrl.Equal(other.ChangelogUrl) { + return false + } + + if !v.Message.Equal(other.Message) { + return false + } + + if !v.Name.Equal(other.Name) { + return false + } + + if !v.Status.Equal(other.Status) { + return false + } + + return true +} + +func (v CloudProjectRancherVersionValue) Type(ctx context.Context) attr.Type { + return CloudProjectRancherVersionType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v CloudProjectRancherVersionValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "cause": ovhtypes.TfStringType{}, + "changelog_url": ovhtypes.TfStringType{}, + "message": ovhtypes.TfStringType{}, + "name": ovhtypes.TfStringType{}, + "status": ovhtypes.TfStringType{}, + } +} diff --git a/ovh/data_cloud_project_rancher_version_test.go b/ovh/data_cloud_project_rancher_version_test.go new file mode 100644 index 000000000..1c38ede36 --- /dev/null +++ b/ovh/data_cloud_project_rancher_version_test.go @@ -0,0 +1,31 @@ +package ovh + +import ( + "fmt" + "os" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func TestAccDataSourceCloudProjectRancherVersion_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheckCloud(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: fmt.Sprintf(` + data "ovh_cloud_project_rancher_version" "versions" { + project_id = "%s" + } + `, os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST")), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.ovh_cloud_project_rancher_version.versions", "project_id", os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST")), + resource.TestCheckResourceAttrSet("data.ovh_cloud_project_rancher_version.versions", "versions.#"), + resource.TestCheckResourceAttrSet("data.ovh_cloud_project_rancher_version.versions", "versions.0.name"), + resource.TestCheckResourceAttrSet("data.ovh_cloud_project_rancher_version.versions", "versions.0.status"), + ), + }, + }, + }) +} diff --git a/ovh/provider_new.go b/ovh/provider_new.go index 03519c994..40c027964 100644 --- a/ovh/provider_new.go +++ b/ovh/provider_new.go @@ -199,6 +199,8 @@ func (p *OvhProvider) DataSources(_ context.Context) []func() datasource.DataSou NewCloudProjectNetworkPrivateDataSource, NewCloudProjectNetworkPrivatesDataSource, NewCloudProjectNetworkPrivateSubnetsDataSource, + NewCloudProjectRancherPlanDataSource, + NewCloudProjectRancherVersionDataSource, NewCloudProjectStorageDataSource, NewCloudProjectStoragesDataSource, NewCloudProjectVolumesDataSource, diff --git a/website/docs/d/cloud_project_rancher_plan.html.markdown b/website/docs/d/cloud_project_rancher_plan.html.markdown new file mode 100644 index 000000000..63b1edf34 --- /dev/null +++ b/website/docs/d/cloud_project_rancher_plan.html.markdown @@ -0,0 +1,35 @@ +--- +subcategory : "Managed Rancher Service" +--- + +# ovh_cloud_project_rancher_plan + +Use this datasource to retrieve information about the Managed Rancher plans available in the given public cloud project. + +## Example Usage + +```hcl +data "ovh_cloud_project_rancher_plan" "plans" { + project_id = "XXXXXX" +} +``` + +## Schema + +### Required + +- `project_id` (String) Project ID + +### Read-Only + +- `plans` (Attributes Set) (see [below for nested schema](#nestedatt--plans)) + + +### Nested Schema for `plans` + +Read-Only: + +- `cause` (String) Cause for an unavailability +- `message` (String) Human-readable description of the unavailability cause +- `name` (String) Name of the plan +- `status` (String) Status of the plan diff --git a/website/docs/d/cloud_project_rancher_version.html.markdown b/website/docs/d/cloud_project_rancher_version.html.markdown new file mode 100644 index 000000000..beb579551 --- /dev/null +++ b/website/docs/d/cloud_project_rancher_version.html.markdown @@ -0,0 +1,36 @@ +--- +subcategory : "Managed Rancher Service" +--- + +# ovh_cloud_project_rancher_version + +Use this datasource to retrieve information about the Managed Rancher available versions in the given public cloud project. + +## Example Usage + +```hcl +data "ovh_cloud_project_rancher_version" "versions" { + project_id = "XXXXXX" +} +``` + +## Schema + +### Required + +- `project_id` (String) Project ID + +### Read-Only + +- `versions` (Attributes Set) (see [below for nested schema](#nestedatt--versions)) + + +### Nested Schema for `versions` + +Read-Only: + +- `cause` (String) Cause for an unavailability +- `changelog_url` (String) Changelog URL of the version +- `message` (String) Human-readable description of the unavailability cause +- `name` (String) Name of the version +- `status` (String) Status of the version