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