2323 _ resource.ResourceWithImportState = & tenantV4Resource {}
2424)
2525
26+ type tenantV4ResourceModel struct {
27+ ApiVersion types.String `tfsdk:"api_version"`
28+ Kind types.String `tfsdk:"kind"`
29+ Metadata tenantV4ResourceMetadataModel `tfsdk:"metadata"`
30+ Spec tenantV4ResourceSpecModel `tfsdk:"spec"`
31+ Status * client.MeshTenantV4Status `tfsdk:"status"`
32+ }
33+
34+ type tenantV4ResourceMetadataModel struct {
35+ Uuid types.String `tfsdk:"uuid"`
36+ OwnedByWorkspace types.String `tfsdk:"owned_by_workspace"`
37+ OwnedByProject types.String `tfsdk:"owned_by_project"`
38+ CreatedOn types.String `tfsdk:"created_on"`
39+ DeletedOn types.String `tfsdk:"deleted_on"`
40+ MarkedForDeletionOn types.String `tfsdk:"marked_for_deletion_on"`
41+ }
42+
43+ type tenantV4ResourceSpecModel struct {
44+ PlatformIdentifier types.String `tfsdk:"platform_identifier"`
45+ PlatformTenantId types.String `tfsdk:"platform_tenant_id"`
46+ LandingZoneIdentifier types.String `tfsdk:"landing_zone_identifier"`
47+ Quotas []tenantQuotaModel `tfsdk:"quotas"`
48+ }
49+
50+ type tenantQuotaModel struct {
51+ Key types.String `tfsdk:"key"`
52+ Value types.Int64 `tfsdk:"value"`
53+ }
54+
2655func NewTenantV4Resource () resource.Resource {
2756 return & tenantV4Resource {}
2857}
@@ -56,17 +85,17 @@ func (r *tenantV4Resource) Configure(_ context.Context, req resource.ConfigureRe
5685
5786func (r * tenantV4Resource ) Schema (_ context.Context , _ resource.SchemaRequest , resp * resource.SchemaResponse ) {
5887 resp .Schema = schema.Schema {
59- MarkdownDescription : "Single tenant by workspace, project, and platform (v4) ." ,
88+ MarkdownDescription : "Manages a `meshTenant` with API version 4 ." ,
6089
6190 Attributes : map [string ]schema.Attribute {
6291 "api_version" : schema.StringAttribute {
63- MarkdownDescription : "Tenant datatype version" ,
92+ MarkdownDescription : "API version of the tenant resource. " ,
6493 Computed : true ,
6594 PlanModifiers : []planmodifier.String {stringplanmodifier .UseStateForUnknown ()},
6695 },
6796
6897 "kind" : schema.StringAttribute {
69- MarkdownDescription : "meshObject type , always `meshTenant`." ,
98+ MarkdownDescription : "The kind of the meshObject , always `meshTenant`." ,
7099 Computed : true ,
71100 Validators : []validator.String {
72101 stringvalidator .OneOf ([]string {"meshTenant" }... ),
@@ -75,28 +104,36 @@ func (r *tenantV4Resource) Schema(_ context.Context, _ resource.SchemaRequest, r
75104 },
76105
77106 "metadata" : schema.SingleNestedAttribute {
78- MarkdownDescription : "Tenant metadata. Workspace, project and platform of the target tenant must be set here." ,
107+ MarkdownDescription : "Metadata of the tenant. The `owned_by_workspace` and `owned_by_project` attributes must be set here." ,
79108 Required : true ,
80109 PlanModifiers : []planmodifier.Object {objectplanmodifier .RequiresReplace ()},
81110 Attributes : map [string ]schema.Attribute {
82111 "uuid" : schema.StringAttribute {
83- MarkdownDescription : "UUID of the tenant." ,
84- Required : true ,
112+ MarkdownDescription : "The unique identifier (UUID) of the tenant." ,
113+ Computed : true ,
114+ PlanModifiers : []planmodifier.String {
115+ stringplanmodifier .UseStateForUnknown (),
116+ },
85117 },
86118 "owned_by_workspace" : schema.StringAttribute {
87- MarkdownDescription : "Identifier of the workspace the tenant belongs to." ,
119+ MarkdownDescription : "The identifier of the workspace that the tenant belongs to." ,
88120 Required : true ,
89121 },
90122 "owned_by_project" : schema.StringAttribute {
91- MarkdownDescription : "Identifier of the project the tenant belongs to." ,
123+ MarkdownDescription : "The identifier of the project that the tenant belongs to." ,
92124 Required : true ,
93125 },
126+ "created_on" : schema.StringAttribute {
127+ MarkdownDescription : "The creation timestamp of the meshTenant (e.g. `2020-12-22T09:37:43Z`)." ,
128+ Computed : true ,
129+ PlanModifiers : []planmodifier.String {stringplanmodifier .UseStateForUnknown ()},
130+ },
94131 "deleted_on" : schema.StringAttribute {
95- MarkdownDescription : "If the tenant has been submitted for deletion by a workspace manager, the date is shown here (e.g. 2020-12-22T09:37:43Z)." ,
132+ MarkdownDescription : "The deletion timestamp of the tenant (e.g. ` 2020-12-22T09:37:43Z` )." ,
96133 Computed : true ,
97134 },
98- "created_on " : schema.StringAttribute {
99- MarkdownDescription : "The date the tenant was created (e.g. 2020-12-22T09:37:43Z)." ,
135+ "marked_for_deletion_on " : schema.StringAttribute {
136+ MarkdownDescription : "The timestamp when the tenant was marked for deletion (e.g. ` 2020-12-22T09:37:43Z` )." ,
100137 Computed : true ,
101138 },
102139 },
@@ -111,24 +148,24 @@ func (r *tenantV4Resource) Schema(_ context.Context, _ resource.SchemaRequest, r
111148 MarkdownDescription : "Identifier of the target platform." ,
112149 Required : true ,
113150 },
114- "local_id " : schema.StringAttribute {
115- MarkdownDescription : "Tenant ID local to the platform (e.g. GCP project ID, Azure subscription ID). Setting the local ID means that a tenant with this ID should be imported into meshStack. Not setting a local ID means that a new tenant should be created. Field will be empty until a successful replication has run." ,
151+ "platform_tenant_id " : schema.StringAttribute {
152+ MarkdownDescription : "The identifier of the tenant on the platform (e.g. GCP project ID or Azure subscription ID). If this is not set, a new tenant will be created. If this is set, an existing tenant will be imported. Otherwise, this field will be empty until a successful replication has run." ,
116153 Optional : true ,
117154 Computed : true ,
118155 },
119156 "landing_zone_identifier" : schema.StringAttribute {
120- MarkdownDescription : "Identifier of landing zone to assign to this tenant." ,
157+ MarkdownDescription : "The identifier of the landing zone to assign to this tenant." ,
121158 Optional : true ,
122159 Computed : true ,
123160 },
124161 "quotas" : schema.ListNestedAttribute {
125- MarkdownDescription : "Set of applied tenant quotas . By default the landing zone quotas are applied to new tenants." ,
162+ MarkdownDescription : "The set of quotas applied to the tenant . By default, the landing zone quotas are applied to new tenants." ,
126163 Optional : true ,
127164 Computed : true ,
128165 NestedObject : schema.NestedAttributeObject {
129166 Attributes : map [string ]schema.Attribute {
130- "key" : schema.StringAttribute {Computed : true },
131- "value" : schema.Int64Attribute {Computed : true },
167+ "key" : schema.StringAttribute {Required : true },
168+ "value" : schema.Int64Attribute {Required : true },
132169 },
133170 },
134171 },
@@ -139,17 +176,21 @@ func (r *tenantV4Resource) Schema(_ context.Context, _ resource.SchemaRequest, r
139176 MarkdownDescription : "Tenant status." ,
140177 Computed : true ,
141178 Attributes : map [string ]schema.Attribute {
142- "tags" : schema.MapAttribute {
143- MarkdownDescription : "Tags assigned to this tenant." ,
144- ElementType : types.ListType {ElemType : types .StringType },
179+ "tenant_name" : schema.StringAttribute {
180+ MarkdownDescription : "The full tenant name, a concatenation of the workspace identifier, project identifier and platform identifier." ,
145181 Computed : true ,
146182 },
147- "last_replicated " : schema.StringAttribute {
148- MarkdownDescription : "The last time the tenant was replicated (e.g. 2020-12-22T09:37:43Z) ." ,
183+ "platform_type_identifier " : schema.StringAttribute {
184+ MarkdownDescription : "Identifier of the platform type ." ,
149185 Computed : true ,
150186 },
151- "current_replication_status" : schema.StringAttribute {
152- MarkdownDescription : "The current replication status of the tenant." ,
187+ "platform_workspace_identifier" : schema.StringAttribute {
188+ MarkdownDescription : "Some platforms create representations of workspaces, in such cases this will contain the identifier of the workspace on the platform." ,
189+ Computed : true ,
190+ },
191+ "tags" : schema.MapAttribute {
192+ MarkdownDescription : "Tags assigned to this tenant." ,
193+ ElementType : types.ListType {ElemType : types .StringType },
153194 Computed : true ,
154195 },
155196 },
@@ -159,22 +200,42 @@ func (r *tenantV4Resource) Schema(_ context.Context, _ resource.SchemaRequest, r
159200}
160201
161202func (r * tenantV4Resource ) Create (ctx context.Context , req resource.CreateRequest , resp * resource.CreateResponse ) {
162- var metadata client.MeshTenantV4CreateMetadata
163- resp .Diagnostics .Append (req .Plan .GetAttribute (ctx , path .Root ("metadata" ), & metadata )... )
164-
165- var spec client.MeshTenantV4CreateSpec
166- resp .Diagnostics .Append (req .Plan .GetAttribute (ctx , path .Root ("spec" ), & spec )... )
203+ var plan tenantV4ResourceModel
204+ resp .Diagnostics .Append (req .Plan .Get (ctx , & plan )... )
167205
168206 if resp .Diagnostics .HasError () {
169207 return
170208 }
171209
172- create := client.MeshTenantV4Create {
173- Metadata : metadata ,
174- Spec : spec ,
210+ createRequest := client.MeshTenantV4Create {
211+ Metadata : client.MeshTenantV4CreateMetadata {
212+ OwnedByProject : plan .Metadata .OwnedByProject .ValueString (),
213+ OwnedByWorkspace : plan .Metadata .OwnedByWorkspace .ValueString (),
214+ },
215+ Spec : client.MeshTenantV4CreateSpec {
216+ PlatformIdentifier : plan .Spec .PlatformIdentifier .ValueString (),
217+ },
175218 }
176219
177- tenant , err := r .client .CreateTenantV4 (& create )
220+ if ! plan .Spec .PlatformTenantId .IsNull () && ! plan .Spec .PlatformTenantId .IsUnknown () {
221+ createRequest .Spec .PlatformTenantId = plan .Spec .PlatformTenantId .ValueStringPointer ()
222+ }
223+ if ! plan .Spec .LandingZoneIdentifier .IsNull () && ! plan .Spec .LandingZoneIdentifier .IsUnknown () {
224+ createRequest .Spec .LandingZoneIdentifier = plan .Spec .LandingZoneIdentifier .ValueStringPointer ()
225+ }
226+
227+ if len (plan .Spec .Quotas ) > 0 {
228+ quotas := make ([]client.MeshTenantQuota , len (plan .Spec .Quotas ))
229+ for i , q := range plan .Spec .Quotas {
230+ quotas [i ] = client.MeshTenantQuota {
231+ Key : q .Key .ValueString (),
232+ Value : q .Value .ValueInt64 (),
233+ }
234+ }
235+ createRequest .Spec .Quotas = & quotas
236+ }
237+
238+ tenant , err := r .client .CreateTenantV4 (& createRequest )
178239 if err != nil {
179240 resp .Diagnostics .AddError (
180241 "Error creating tenant" ,
@@ -186,19 +247,25 @@ func (r *tenantV4Resource) Create(ctx context.Context, req resource.CreateReques
186247 resp .Diagnostics .Append (resp .State .Set (ctx , tenant )... )
187248}
188249
250+ func (r * tenantV4Resource ) Update (ctx context.Context , req resource.UpdateRequest , resp * resource.UpdateResponse ) {
251+ resp .Diagnostics .AddError ("Tenants can't be updated" , "Unsupported operation: tenant can't be updated." )
252+ }
253+
189254func (r * tenantV4Resource ) Read (ctx context.Context , req resource.ReadRequest , resp * resource.ReadResponse ) {
190- var uuid string
191- resp .Diagnostics .Append (req .State .GetAttribute (ctx , path . Root ( "metadata" ). AtName ( "uuid" ), & uuid )... )
255+ var state tenantV4ResourceModel
256+ resp .Diagnostics .Append (req .State .Get (ctx , & state )... )
192257
193258 if resp .Diagnostics .HasError () {
194259 return
195260 }
196261
262+ uuid := state .Metadata .Uuid .ValueString ()
263+
197264 tenant , err := r .client .ReadTenantV4 (uuid )
198265 if err != nil {
199266 resp .Diagnostics .AddError (
200267 "Error reading tenant" ,
201- fmt .Sprintf ("Could not read tenant, unexpected error: %s" , err .Error ()),
268+ fmt .Sprintf ("Could not read tenant with uuid %s , unexpected error: %s" , uuid , err .Error ()),
202269 )
203270 return
204271 }
@@ -211,71 +278,26 @@ func (r *tenantV4Resource) Read(ctx context.Context, req resource.ReadRequest, r
211278 resp .Diagnostics .Append (resp .State .Set (ctx , tenant )... )
212279}
213280
214- func (r * tenantV4Resource ) Update (ctx context.Context , req resource.UpdateRequest , resp * resource.UpdateResponse ) {
215- var metadata client.MeshTenantV4CreateMetadata
216- resp .Diagnostics .Append (req .Plan .GetAttribute (ctx , path .Root ("metadata" ), & metadata )... )
217-
218- var spec client.MeshTenantV4CreateSpec
219- resp .Diagnostics .Append (req .Plan .GetAttribute (ctx , path .Root ("spec" ), & spec )... )
220-
221- if resp .Diagnostics .HasError () {
222- return
223- }
224-
225- update := client.MeshTenantV4Create {
226- Metadata : metadata ,
227- Spec : spec ,
228- }
229-
230- tenant , err := r .client .CreateTenantV4 (& update )
231- if err != nil {
232- resp .Diagnostics .AddError (
233- "Error updating tenant" ,
234- fmt .Sprintf ("Could not update tenant, unexpected error: %s" , err .Error ()),
235- )
236- return
237- }
238-
239- resp .Diagnostics .Append (resp .State .Set (ctx , tenant )... )
240- }
241-
242281func (r * tenantV4Resource ) Delete (ctx context.Context , req resource.DeleteRequest , resp * resource.DeleteResponse ) {
243- var uuid string
244- resp .Diagnostics .Append (req .State .GetAttribute (ctx , path . Root ( "metadata" ). AtName ( "uuid" ), & uuid )... )
282+ var state tenantV4ResourceModel
283+ resp .Diagnostics .Append (req .State .Get (ctx , & state )... )
245284
246285 if resp .Diagnostics .HasError () {
247286 return
248287 }
249288
289+ uuid := state .Metadata .Uuid .ValueString ()
290+
250291 err := r .client .DeleteTenantV4 (uuid )
251292 if err != nil {
252293 resp .Diagnostics .AddError (
253294 "Error deleting tenant" ,
254- fmt .Sprintf ("Could not delete tenant, unexpected error: %s" , err .Error ()),
295+ fmt .Sprintf ("Could not delete tenant with uuid %s , unexpected error: %s" , uuid , err .Error ()),
255296 )
256297 return
257298 }
258299}
259300
260301func (r * tenantV4Resource ) ImportState (ctx context.Context , req resource.ImportStateRequest , resp * resource.ImportStateResponse ) {
261- uuid := req .ID
262-
263- tenant , err := r .client .ReadTenantV4 (uuid )
264- if err != nil {
265- resp .Diagnostics .AddError (
266- "Error importing tenant" ,
267- fmt .Sprintf ("Could not import tenant, unexpected error: %s" , err .Error ()),
268- )
269- return
270- }
271-
272- if tenant == nil {
273- resp .Diagnostics .AddError (
274- "Error importing tenant" ,
275- "Tenant not found" ,
276- )
277- return
278- }
279-
280- resp .Diagnostics .Append (resp .State .Set (ctx , tenant )... )
302+ resource .ImportStatePassthroughID (ctx , path .Root ("metadata" ).AtName ("uuid" ), req , resp )
281303}
0 commit comments