@@ -29,6 +29,7 @@ import (
29
29
"github.com/hashicorp/terraform-plugin-log/tflog"
30
30
"github.com/juju/errors"
31
31
"github.com/juju/juju/core/constraints"
32
+ "github.com/juju/juju/core/model"
32
33
jujustorage "github.com/juju/juju/storage"
33
34
34
35
"github.com/juju/terraform-provider-juju/internal/juju"
@@ -82,6 +83,7 @@ type applicationResourceModel struct {
82
83
Constraints types.String `tfsdk:"constraints"`
83
84
Expose types.List `tfsdk:"expose"`
84
85
ModelName types.String `tfsdk:"model"`
86
+ ModelType types.String `tfsdk:"model_type"`
85
87
Placement types.String `tfsdk:"placement"`
86
88
EndpointBindings types.Set `tfsdk:"endpoint_bindings"`
87
89
Resources types.Map `tfsdk:"resources"`
@@ -147,6 +149,14 @@ func (r *applicationResource) Schema(_ context.Context, _ resource.SchemaRequest
147
149
stringplanmodifier .RequiresReplaceIfConfigured (),
148
150
},
149
151
},
152
+ "model_type" : schema.StringAttribute {
153
+ Description : "" ,
154
+ Computed : true ,
155
+ Optional : true ,
156
+ PlanModifiers : []planmodifier.String {
157
+ stringplanmodifier .UseStateForUnknown (),
158
+ },
159
+ },
150
160
"units" : schema.Int64Attribute {
151
161
Description : "The number of application units to deploy for the charm." ,
152
162
Optional : true ,
@@ -321,6 +331,18 @@ func (r *applicationResource) Schema(_ context.Context, _ resource.SchemaRequest
321
331
Computed : true ,
322
332
PlanModifiers : []planmodifier.String {
323
333
stringplanmodifier .UseStateForUnknown (),
334
+ stringplanmodifier .RequiresReplaceIf (func (ctx context.Context , req planmodifier.StringRequest , resp * stringplanmodifier.RequiresReplaceIfFuncResponse ) {
335
+ if req .State .Raw .IsKnown () {
336
+ var state applicationResourceModel
337
+ diags := req .State .Get (ctx , & state )
338
+ if diags .HasError () {
339
+ resp .Diagnostics .Append (diags ... )
340
+ return
341
+ }
342
+ modelType := state .ModelType .ValueString ()
343
+ resp .RequiresReplace = modelType == model .IAAS .String ()
344
+ }
345
+ }, "" , "" ),
324
346
},
325
347
Validators : []validator.String {
326
348
stringvalidator .ConflictsWith (path.Expressions {
@@ -582,6 +604,11 @@ func (r *applicationResource) Create(ctx context.Context, req resource.CreateReq
582
604
}
583
605
r .trace (fmt .Sprintf ("read application resource %q" , createResp .AppName ))
584
606
607
+ modelType , err := r .client .Applications .ModelType (modelName )
608
+ if err != nil {
609
+ resp .Diagnostics .Append (handleApplicationNotFoundError (ctx , err , & resp .State )... )
610
+ return
611
+ }
585
612
// Save plan into Terraform state
586
613
587
614
// Constraints do not apply to subordinate applications. If the application
@@ -590,6 +617,7 @@ func (r *applicationResource) Create(ctx context.Context, req resource.CreateReq
590
617
plan .Placement = types .StringValue (readResp .Placement )
591
618
plan .Principal = types .BoolNull ()
592
619
plan .ApplicationName = types .StringValue (createResp .AppName )
620
+ plan .ModelType = types .StringValue (modelType .String ())
593
621
planCharm .Revision = types .Int64Value (int64 (readResp .Revision ))
594
622
planCharm .Base = types .StringValue (readResp .Base )
595
623
planCharm .Series = types .StringValue (readResp .Series )
@@ -692,6 +720,12 @@ func (r *applicationResource) Read(ctx context.Context, req resource.ReadRequest
692
720
}
693
721
r .trace ("read application" , map [string ]interface {}{"resource" : appName , "response" : response })
694
722
723
+ modelType , err := r .client .Applications .ModelType (modelName )
724
+ if err != nil {
725
+ resp .Diagnostics .Append (handleApplicationNotFoundError (ctx , err , & resp .State )... )
726
+ return
727
+ }
728
+
695
729
state .ApplicationName = types .StringValue (appName )
696
730
state .ModelName = types .StringValue (modelName )
697
731
@@ -700,6 +734,7 @@ func (r *applicationResource) Read(ctx context.Context, req resource.ReadRequest
700
734
state .Placement = types .StringValue (response .Placement )
701
735
state .Principal = types .BoolNull ()
702
736
state .UnitCount = types .Int64Value (int64 (response .Units ))
737
+ state .ModelType = types .StringValue (modelType .String ())
703
738
state .Trust = types .BoolValue (response .Trust )
704
739
705
740
// state requiring transformation
@@ -919,16 +954,18 @@ func (r *applicationResource) Update(ctx context.Context, req resource.UpdateReq
919
954
} else if ! planCharm .Revision .Equal (stateCharm .Revision ) {
920
955
updateApplicationInput .Revision = intPtr (planCharm .Revision )
921
956
}
922
-
923
- if ! planCharm .Series .Equal (stateCharm .Series ) || ! planCharm .Base .Equal (stateCharm .Base ) {
957
+ if ! planCharm .Base .Equal (stateCharm .Base ) {
958
+ updateApplicationInput .Base = planCharm .Base .ValueString ()
959
+ }
960
+ if ! planCharm .Series .Equal (stateCharm .Series ) {
924
961
// This violates Terraform's declarative model. We could implement
925
962
// `juju set-application-base`, usually used after `upgrade-machine`,
926
963
// which would change the operating system used for future units of
927
964
// the application provided the charm supported it, but not change
928
965
// the current. This provider does not implement an equivalent to
929
966
// `upgrade-machine`. There is also a question of how to handle a
930
967
// change to series, revision and channel at the same time.
931
- resp .Diagnostics .AddWarning ("Not Supported" , "Changing an application 's operating system after deploy." )
968
+ resp .Diagnostics .AddWarning ("Not Supported" , "Changing operating system 's series after deploy." )
932
969
}
933
970
}
934
971
@@ -1051,7 +1088,8 @@ func (r *applicationResource) Update(ctx context.Context, req resource.UpdateReq
1051
1088
if updateApplicationInput .Channel != "" ||
1052
1089
updateApplicationInput .Revision != nil ||
1053
1090
updateApplicationInput .Placement != nil ||
1054
- updateApplicationInput .Units != nil {
1091
+ updateApplicationInput .Units != nil ||
1092
+ updateApplicationInput .Base != "" {
1055
1093
readResp , err := r .client .Applications .ReadApplicationWithRetryOnNotFound (ctx , & juju.ReadApplicationInput {
1056
1094
ModelName : updateApplicationInput .ModelName ,
1057
1095
AppName : updateApplicationInput .AppName ,
@@ -1090,6 +1128,7 @@ func (r *applicationResource) Update(ctx context.Context, req resource.UpdateReq
1090
1128
}
1091
1129
}
1092
1130
1131
+ plan .ModelType = state .ModelType
1093
1132
plan .ID = types .StringValue (newAppID (plan .ModelName .ValueString (), plan .ApplicationName .ValueString ()))
1094
1133
plan .Principal = types .BoolNull ()
1095
1134
r .trace ("Updated" , applicationResourceModelForLogging (ctx , & plan ))
0 commit comments