Skip to content

Commit ba187bb

Browse files
malhussanhenryde
authored andcommitted
feat: meshstack_tenant_v4 resource
1 parent fbaf47c commit ba187bb

File tree

6 files changed

+551
-0
lines changed

6 files changed

+551
-0
lines changed

client/tenant_v4.go

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
package client
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
"fmt"
7+
"io"
8+
"net/http"
9+
"net/url"
10+
)
11+
12+
const CONTENT_TYPE_TENANT_V4 = "application/vnd.meshcloud.api.meshtenant.v4.hal+json"
13+
14+
type MeshTenantV4 struct {
15+
ApiVersion string `json:"apiVersion" tfsdk:"api_version"`
16+
Kind string `json:"kind" tfsdk:"kind"`
17+
Metadata MeshTenantMetadataV4 `json:"metadata" tfsdk:"metadata"`
18+
Spec MeshTenantSpecV4 `json:"spec" tfsdk:"spec"`
19+
Status MeshTenantStatusV4 `json:"status" tfsdk:"status"`
20+
}
21+
22+
type MeshTenantMetadataV4 struct {
23+
UUID string `json:"uuid" tfsdk:"uuid"`
24+
OwnedByProject string `json:"ownedByProject" tfsdk:"owned_by_project"`
25+
OwnedByWorkspace string `json:"ownedByWorkspace" tfsdk:"owned_by_workspace"`
26+
DeletedOn *string `json:"deletedOn" tfsdk:"deleted_on"`
27+
CreatedOn *string `json:"createdOn" tfsdk:"created_on"`
28+
}
29+
30+
type MeshTenantSpecV4 struct {
31+
PlatformIdentifier string `json:"platformIdentifier" tfsdk:"platform_identifier"`
32+
LocalId *string `json:"localId" tfsdk:"local_id"`
33+
LandingZoneIdentifier string `json:"landingZoneIdentifier" tfsdk:"landing_zone_identifier"`
34+
Quotas []MeshTenantQuota `json:"quotas" tfsdk:"quotas"`
35+
}
36+
37+
type MeshTenantStatusV4 struct {
38+
Tags map[string][]string `json:"tags" tfsdk:"tags"`
39+
LastReplicated *string `json:"lastReplicated" tfsdk:"last_replicated"`
40+
CurrentReplicationStatus string `json:"currentReplicationStatus" tfsdk:"current_replication_status"`
41+
}
42+
43+
type MeshTenantCreateV4 struct {
44+
Metadata MeshTenantCreateMetadataV4 `json:"metadata" tfsdk:"metadata"`
45+
Spec MeshTenantCreateSpecV4 `json:"spec" tfsdk:"spec"`
46+
}
47+
48+
type MeshTenantCreateMetadataV4 struct {
49+
UUID string `json:"uuid" tfsdk:"uuid"`
50+
OwnedByProject string `json:"ownedByProject" tfsdk:"owned_by_project"`
51+
OwnedByWorkspace string `json:"ownedByWorkspace" tfsdk:"owned_by_workspace"`
52+
}
53+
54+
type MeshTenantCreateSpecV4 struct {
55+
PlatformIdentifier string `json:"platformIdentifier" tfsdk:"platform_identifier"`
56+
LocalId *string `json:"localId" tfsdk:"local_id"`
57+
LandingZoneIdentifier string `json:"landingZoneIdentifier" tfsdk:"landing_zone_identifier"`
58+
Quotas []MeshTenantQuota `json:"quotas" tfsdk:"quotas"`
59+
}
60+
61+
func (c *MeshStackProviderClient) urlForTenantV4(uuid string) *url.URL {
62+
return c.endpoints.Tenants.JoinPath(uuid)
63+
}
64+
65+
func (c *MeshStackProviderClient) ReadTenantV4(uuid string) (*MeshTenantV4, error) {
66+
targetUrl := c.urlForTenantV4(uuid)
67+
req, err := http.NewRequest("GET", targetUrl.String(), nil)
68+
if err != nil {
69+
return nil, err
70+
}
71+
req.Header.Set("Accept", CONTENT_TYPE_TENANT_V4)
72+
73+
res, err := c.doAuthenticatedRequest(req)
74+
if err != nil {
75+
return nil, err
76+
}
77+
78+
defer res.Body.Close()
79+
80+
data, err := io.ReadAll(res.Body)
81+
if err != nil {
82+
return nil, err
83+
}
84+
85+
if res.StatusCode == 404 {
86+
return nil, nil
87+
}
88+
89+
if res.StatusCode != 200 {
90+
return nil, fmt.Errorf("unexpected status code: %d, %s", res.StatusCode, data)
91+
}
92+
93+
var tenant MeshTenantV4
94+
err = json.Unmarshal(data, &tenant)
95+
if err != nil {
96+
return nil, err
97+
}
98+
99+
return &tenant, nil
100+
}
101+
102+
func (c *MeshStackProviderClient) CreateTenantV4(tenant *MeshTenantCreateV4) (*MeshTenantV4, error) {
103+
payload, err := json.Marshal(tenant)
104+
if err != nil {
105+
return nil, err
106+
}
107+
108+
req, err := http.NewRequest("POST", c.endpoints.Tenants.String(), bytes.NewBuffer(payload))
109+
if err != nil {
110+
return nil, err
111+
}
112+
req.Header.Set("Content-Type", CONTENT_TYPE_TENANT_V4)
113+
req.Header.Set("Accept", CONTENT_TYPE_TENANT_V4)
114+
115+
res, err := c.doAuthenticatedRequest(req)
116+
if err != nil {
117+
return nil, err
118+
}
119+
120+
defer res.Body.Close()
121+
122+
data, err := io.ReadAll(res.Body)
123+
if err != nil {
124+
return nil, err
125+
}
126+
127+
if res.StatusCode != 200 {
128+
return nil, fmt.Errorf("unexpected status code: %d, %s", res.StatusCode, data)
129+
}
130+
131+
var createdTenant MeshTenantV4
132+
err = json.Unmarshal(data, &createdTenant)
133+
if err != nil {
134+
return nil, err
135+
}
136+
137+
return &createdTenant, nil
138+
}
139+
140+
func (c *MeshStackProviderClient) DeleteTenantV4(uuid string) error {
141+
targetUrl := c.urlForTenantV4(uuid)
142+
return c.deleteMeshObject(*targetUrl, 202)
143+
}

docs/resources/tenant_v4.md

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "meshstack_tenant_v4 Resource - terraform-provider-meshstack"
4+
subcategory: ""
5+
description: |-
6+
Single tenant by workspace, project, and platform (v4).
7+
---
8+
9+
# meshstack_tenant_v4 (Resource)
10+
11+
Single tenant by workspace, project, and platform (v4).
12+
13+
## Example Usage
14+
15+
```terraform
16+
data "meshstack_project" "example" {
17+
metadata = {
18+
name = "my-project-identifier"
19+
owned_by_workspace = "my-workspace-identifier"
20+
}
21+
}
22+
23+
resource "meshstack_tenant_v4" "example" {
24+
metadata = {
25+
uuid = "1234-5345234-213123-123123"
26+
owned_by_workspace = data.meshstack_project.example.metadata.owned_by_workspace
27+
owned_by_project = data.meshstack_project.example.metadata.name
28+
}
29+
30+
spec = {
31+
platform_identifier = "my-platform-identifier"
32+
landing_zone_identifier = "platform-landing-zone-identifier"
33+
}
34+
}
35+
```
36+
37+
<!-- schema generated by tfplugindocs -->
38+
## Schema
39+
40+
### Required
41+
42+
- `metadata` (Attributes) Tenant metadata. Workspace, project and platform of the target tenant must be set here. (see [below for nested schema](#nestedatt--metadata))
43+
- `spec` (Attributes) Tenant specification. (see [below for nested schema](#nestedatt--spec))
44+
45+
### Read-Only
46+
47+
- `api_version` (String) Tenant datatype version
48+
- `kind` (String) meshObject type, always `meshTenant`.
49+
- `status` (Attributes) Tenant status. (see [below for nested schema](#nestedatt--status))
50+
51+
<a id="nestedatt--metadata"></a>
52+
### Nested Schema for `metadata`
53+
54+
Required:
55+
56+
- `owned_by_project` (String) Identifier of the project the tenant belongs to.
57+
- `owned_by_workspace` (String) Identifier of the workspace the tenant belongs to.
58+
- `uuid` (String) UUID of the tenant.
59+
60+
Read-Only:
61+
62+
- `created_on` (String) The date the tenant was created (e.g. 2020-12-22T09:37:43Z).
63+
- `deleted_on` (String) If the tenant has been submitted for deletion by a workspace manager, the date is shown here (e.g. 2020-12-22T09:37:43Z).
64+
65+
66+
<a id="nestedatt--spec"></a>
67+
### Nested Schema for `spec`
68+
69+
Required:
70+
71+
- `platform_identifier` (String) Identifier of the target platform.
72+
73+
Optional:
74+
75+
- `landing_zone_identifier` (String) Identifier of landing zone to assign to this tenant.
76+
- `local_id` (String) 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.
77+
- `quotas` (Attributes List) Set of applied tenant quotas. By default the landing zone quotas are applied to new tenants. (see [below for nested schema](#nestedatt--spec--quotas))
78+
79+
<a id="nestedatt--spec--quotas"></a>
80+
### Nested Schema for `spec.quotas`
81+
82+
Read-Only:
83+
84+
- `key` (String)
85+
- `value` (Number)
86+
87+
88+
89+
<a id="nestedatt--status"></a>
90+
### Nested Schema for `status`
91+
92+
Read-Only:
93+
94+
- `current_replication_status` (String) The current replication status of the tenant.
95+
- `last_replicated` (String) The last time the tenant was replicated (e.g. 2020-12-22T09:37:43Z).
96+
- `tags` (Map of List of String) Tags assigned to this tenant.
97+
98+
## Import
99+
100+
Import is supported using the following syntax:
101+
102+
```shell
103+
# import via uuid
104+
terraform import 'meshstack_tenant.example' '00000000-0000-0000-0000-000000000000'
105+
```
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# import via uuid
2+
terraform import 'meshstack_tenant.example' '00000000-0000-0000-0000-000000000000'
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
data "meshstack_project" "example" {
2+
metadata = {
3+
name = "my-project-identifier"
4+
owned_by_workspace = "my-workspace-identifier"
5+
}
6+
}
7+
8+
resource "meshstack_tenant_v4" "example" {
9+
metadata = {
10+
uuid = "1234-5345234-213123-123123"
11+
owned_by_workspace = data.meshstack_project.example.metadata.owned_by_workspace
12+
owned_by_project = data.meshstack_project.example.metadata.name
13+
}
14+
15+
spec = {
16+
platform_identifier = "my-platform-identifier"
17+
landing_zone_identifier = "platform-landing-zone-identifier"
18+
}
19+
}

internal/provider/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ func (p *MeshStackProvider) Resources(ctx context.Context) []func() resource.Res
105105
return []func() resource.Resource{
106106
NewProjectResource,
107107
NewTenantResource,
108+
NewTenantResourceV4,
108109
NewProjectUserBindingResource,
109110
NewProjectGroupBindingResource,
110111
NewBuildingBlockResource,

0 commit comments

Comments
 (0)