Skip to content

Commit 97f95b3

Browse files
committed
feat: support meshLandingZones
CU-86c57xgjy
1 parent 212f1f3 commit 97f95b3

18 files changed

+1620
-0
lines changed

client/client.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ type endpoints struct {
4242
WorkspaceGroupBindings *url.URL `json:"meshworkspacegroupbindings"`
4343
Tenants *url.URL `json:"meshtenants"`
4444
TagDefinitions *url.URL `json:"meshtagdefinitions"`
45+
LandingZones *url.URL `json:"meshlandingzones"`
4546
}
4647

4748
type loginResponse struct {
@@ -71,6 +72,7 @@ func NewClient(rootUrl *url.URL, apiKey string, apiSecret string) (*MeshStackPro
7172
WorkspaceGroupBindings: rootUrl.JoinPath(apiMeshObjectsRoot, "meshworkspacebindings", "groupbindings"),
7273
Tenants: rootUrl.JoinPath(apiMeshObjectsRoot, "meshtenants"),
7374
TagDefinitions: rootUrl.JoinPath(apiMeshObjectsRoot, "meshtagdefinitions"),
75+
LandingZones: rootUrl.JoinPath(apiMeshObjectsRoot, "meshlandingzones"),
7476
}
7577

7678
return client, nil

client/landingzone.go

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
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_LANDINGZONE = "application/vnd.meshcloud.api.meshlandingzone.v1-preview.hal+json"
13+
14+
type MeshLandingZone struct {
15+
ApiVersion string `json:"apiVersion" tfsdk:"api_version"`
16+
Kind string `json:"kind" tfsdk:"kind"`
17+
Metadata MeshLandingZoneMetadata `json:"metadata" tfsdk:"metadata"`
18+
Spec MeshLandingZoneSpec `json:"spec" tfsdk:"spec"`
19+
}
20+
21+
type MeshLandingZoneMetadata struct {
22+
Name string `json:"name" tfsdk:"name"`
23+
Tags map[string][]string `json:"tags" tfsdk:"tags"`
24+
}
25+
26+
type MeshLandingZoneSpec struct {
27+
DisplayName string `json:"displayName" tfsdk:"display_name"`
28+
Description string `json:"description" tfsdk:"description"`
29+
AutomateDeletionApproval bool `json:"automateDeletionApproval" tfsdk:"automate_deletion_approval"`
30+
AutomateDeletionReplication bool `json:"automateDeletionReplication" tfsdk:"automate_deletion_replication"`
31+
InfoLink string `json:"infoLink" tfsdk:"info_link"`
32+
PlatformRef PlatformRef `json:"platformRef" tfsdk:"platform_ref"`
33+
PlatformProperties *PlatformProperties `json:"platformProperties,omitempty" tfsdk:"platform_properties"`
34+
}
35+
36+
type PlatformRef struct {
37+
Uuid string `json:"uuid" tfsdk:"uuid"`
38+
Kind string `json:"kind" tfsdk:"kind"`
39+
}
40+
41+
type PlatformProperties struct {
42+
Type string `json:"type" tfsdk:"type"`
43+
AWS *AwsPlatformProperties `json:"aws" tfsdk:"aws"`
44+
AKS *AksPlatformProperties `json:"aks" tfsdk:"aks"`
45+
Azure *AzurePlatformProperties `json:"azure" tfsdk:"azure"`
46+
AzureRG *AzureRgPlatformProperties `json:"azurerg" tfsdk:"azurerg"`
47+
GCP *GcpPlatformProperties `json:"gcp" tfsdk:"gcp"`
48+
Kubernetes *KubernetesPlatformProperties `json:"kubernetes" tfsdk:"kubernetes"`
49+
OpenShift *OpenShiftPlatformProperties `json:"openshift" tfsdk:"openshift"`
50+
}
51+
52+
type MeshLandingZoneCreate struct {
53+
ApiVersion string `json:"apiVersion" tfsdk:"api_version"`
54+
Metadata MeshLandingZoneCreateMetadata `json:"metadata" tfsdk:"metadata"`
55+
Spec MeshLandingZoneSpec `json:"spec" tfsdk:"spec"`
56+
}
57+
type MeshLandingZoneCreateMetadata struct {
58+
Name string `json:"name" tfsdk:"name"`
59+
Tags map[string][]string `json:"tags" tfsdk:"tags"`
60+
}
61+
62+
func (c *MeshStackProviderClient) urlForLandingZone(name string) *url.URL {
63+
return c.endpoints.LandingZones.JoinPath(name)
64+
}
65+
66+
func (c *MeshStackProviderClient) ReadLandingZone(name string) (*MeshLandingZone, error) {
67+
targetUrl := c.urlForLandingZone(name)
68+
req, err := http.NewRequest("GET", targetUrl.String(), nil)
69+
if err != nil {
70+
return nil, err
71+
}
72+
req.Header.Set("Accept", CONTENT_TYPE_LANDINGZONE)
73+
74+
res, err := c.doAuthenticatedRequest(req)
75+
if err != nil {
76+
return nil, err
77+
}
78+
79+
defer res.Body.Close()
80+
81+
if res.StatusCode == http.StatusNotFound {
82+
return nil, nil // Not found is not an error
83+
}
84+
85+
data, err := io.ReadAll(res.Body)
86+
if err != nil {
87+
return nil, err
88+
}
89+
90+
if !isSuccessHTTPStatus(res) {
91+
return nil, fmt.Errorf("unexpected status code: %d, %s", res.StatusCode, data)
92+
}
93+
94+
var landingZone MeshLandingZone
95+
err = json.Unmarshal(data, &landingZone)
96+
if err != nil {
97+
return nil, err
98+
}
99+
return &landingZone, nil
100+
}
101+
102+
func (c *MeshStackProviderClient) CreateLandingZone(landingZone *MeshLandingZoneCreate) (*MeshLandingZone, error) {
103+
payload, err := json.Marshal(landingZone)
104+
if err != nil {
105+
return nil, err
106+
}
107+
108+
req, err := http.NewRequest("POST", c.endpoints.LandingZones.String(), bytes.NewBuffer(payload))
109+
if err != nil {
110+
return nil, err
111+
}
112+
req.Header.Set("Content-Type", CONTENT_TYPE_LANDINGZONE)
113+
req.Header.Set("Accept", CONTENT_TYPE_LANDINGZONE)
114+
115+
res, err := c.doAuthenticatedRequest(req)
116+
if err != nil {
117+
return nil, err
118+
}
119+
defer res.Body.Close()
120+
121+
data, err := io.ReadAll(res.Body)
122+
if err != nil {
123+
return nil, err
124+
}
125+
126+
if !isSuccessHTTPStatus(res) {
127+
return nil, fmt.Errorf("unexpected status code: %d, %s", res.StatusCode, data)
128+
}
129+
130+
var createdLandingZone MeshLandingZone
131+
err = json.Unmarshal(data, &createdLandingZone)
132+
if err != nil {
133+
return nil, err
134+
}
135+
return &createdLandingZone, nil
136+
}
137+
138+
func (c *MeshStackProviderClient) UpdateLandingZone(name string, landingZone *MeshLandingZoneCreate) (*MeshLandingZone, error) {
139+
targetUrl := c.urlForLandingZone(name)
140+
141+
payload, err := json.Marshal(landingZone)
142+
if err != nil {
143+
return nil, err
144+
}
145+
146+
req, err := http.NewRequest("PUT", targetUrl.String(), bytes.NewBuffer(payload))
147+
if err != nil {
148+
return nil, err
149+
}
150+
req.Header.Set("Content-Type", CONTENT_TYPE_LANDINGZONE)
151+
req.Header.Set("Accept", CONTENT_TYPE_LANDINGZONE)
152+
153+
res, err := c.doAuthenticatedRequest(req)
154+
if err != nil {
155+
return nil, err
156+
}
157+
defer res.Body.Close()
158+
159+
data, err := io.ReadAll(res.Body)
160+
if err != nil {
161+
return nil, err
162+
}
163+
164+
if !isSuccessHTTPStatus(res) {
165+
return nil, fmt.Errorf("unexpected status code: %d, %s", res.StatusCode, data)
166+
}
167+
168+
var updatedLandingZone MeshLandingZone
169+
err = json.Unmarshal(data, &updatedLandingZone)
170+
if err != nil {
171+
return nil, err
172+
}
173+
return &updatedLandingZone, nil
174+
}
175+
176+
func (c *MeshStackProviderClient) DeleteLandingZone(name string) error {
177+
targetUrl := c.urlForLandingZone(name)
178+
return c.deleteMeshObject(*targetUrl, 204)
179+
}

client/platform_properties_aks.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package client
2+
3+
type AksPlatformProperties struct {
4+
KubernetesRoleMappings []KubernetesRoleMapping `json:"kubernetesRoleMappings" tfsdk:"kubernetes_role_mappings"`
5+
}
6+
7+
type KubernetesRoleMapping struct {
8+
MeshProjectRoleRef MeshProjectRoleRefV2 `json:"projectRoleRef" tfsdk:"project_role_ref"`
9+
PlatformRoles []string `json:"platformRoles" tfsdk:"platform_roles"`
10+
}

client/platform_properties_aws.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package client
2+
3+
type AwsPlatformProperties struct {
4+
AwsTargetOrgUnitId string `json:"awsTargetOrgUnitId" tfsdk:"aws_target_org_unit_id"`
5+
AwsEnrollAccount bool `json:"awsEnrollAccount" tfsdk:"aws_enroll_account"`
6+
AwsLambdaArn *string `json:"awsLambdaArn" tfsdk:"aws_lambda_arn"`
7+
AwsRoleMappings []AwsRoleMapping `json:"awsRoleMappings" tfsdk:"aws_role_mappings"`
8+
}
9+
10+
type AwsRoleMapping struct {
11+
MeshProjectRoleRef MeshProjectRoleRefV2 `json:"projectRoleRef" tfsdk:"project_role_ref"`
12+
PlatformRole string `json:"platformRole" tfsdk:"platform_role"`
13+
Policies []string `json:"policies" tfsdk:"policies"`
14+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package client
2+
3+
type AzurePlatformProperties struct {
4+
AzureRoleMappings []AzureRoleMapping `json:"azureRoleMappings" tfsdk:"azure_role_mappings"`
5+
AzureManagementGroupId string `json:"azureManagementGroupId" tfsdk:"azure_management_group_id"`
6+
}
7+
8+
type AzureRoleMapping struct {
9+
MeshProjectRoleRef MeshProjectRoleRefV2 `json:"projectRoleRef" tfsdk:"project_role_ref"`
10+
AzureGroupSuffix string `json:"azureGroupSuffix" tfsdk:"azure_group_suffix"`
11+
AzureRoleDefinitions []AzureRoleDefinition `json:"azureRoleDefinitions" tfsdk:"azure_role_definitions"`
12+
}
13+
14+
type AzureRoleDefinition struct {
15+
AzureRoleDefinitionId string `json:"azureRoleDefinitionId" tfsdk:"azure_role_definition_id"`
16+
AbacCondition *string `json:"abacCondition" tfsdk:"abac_condition"`
17+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package client
2+
3+
type AzureRgPlatformProperties struct {
4+
AzureRgLocation string `json:"azureRgLocation" tfsdk:"azure_rg_location"`
5+
AzureRgRoleMappings []AzureRgRoleMapping `json:"azureRgRoleMappings" tfsdk:"azure_rg_role_mappings"`
6+
AzureFunction *AzureFunction `json:"azureFunction,omitempty" tfsdk:"azure_function"`
7+
}
8+
9+
type AzureRgRoleMapping struct {
10+
MeshProjectRoleRef MeshProjectRoleRefV2 `json:"projectRoleRef" tfsdk:"project_role_ref"`
11+
AzureGroupSuffix string `json:"azureGroupSuffix" tfsdk:"azure_group_suffix"`
12+
AzureRoleDefinitionIds []string `json:"azureRoleDefinitionIds" tfsdk:"azure_role_definition_ids"`
13+
}
14+
15+
type AzureFunction struct {
16+
AzureFunctionUrl string `json:"azureFunctionUrl" tfsdk:"azure_function_url"`
17+
AzureFunctionScope string `json:"azureFunctionScope" tfsdk:"azure_function_scope"`
18+
}

client/platform_properties_gcp.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package client
2+
3+
type GcpPlatformProperties struct {
4+
GcpCloudFunctionUrl *string `json:"gcpCloudFunctionUrl,omitempty" tfsdk:"gcp_cloud_function_url"`
5+
GcpFolderId *string `json:"gcpFolderId,omitempty" tfsdk:"gcp_folder_id"`
6+
GcpRoleMappings []GcpRoleMapping `json:"gcpRoleMappings" tfsdk:"gcp_role_mappings"`
7+
}
8+
9+
type GcpRoleMapping struct {
10+
MeshProjectRoleRef MeshProjectRoleRefV2 `json:"projectRoleRef" tfsdk:"project_role_ref"`
11+
PlatformRoles []string `json:"platformRoles" tfsdk:"platform_roles"`
12+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package client
2+
3+
type KubernetesPlatformProperties struct {
4+
KubernetesRoleMappings []KubernetesRoleMapping `json:"kubernetesRoleMappings" tfsdk:"kubernetes_role_mappings"`
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package client
2+
3+
type OpenShiftPlatformProperties struct {
4+
OpenShiftTemplate *string `json:"openShiftTemplate,omitempty" tfsdk:"openshift_template"`
5+
}

client/project_binding.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,17 @@ type MeshProjectBindingMetadata struct {
2222
Name string `json:"name" tfsdk:"name"`
2323
}
2424

25+
// Deprecated: Use MeshProjectRoleRefV2 if possible. The convention is to also provide the `kind`,
26+
// so this struct should only be used for meshobjects that violate our API conventions.
2527
type MeshProjectRoleRef struct {
2628
Name string `json:"name" tfsdk:"name"`
2729
}
2830

31+
type MeshProjectRoleRefV2 struct {
32+
Name string `json:"name" tfsdk:"name"`
33+
Kind string `json:"kind" tfsdk:"kind"`
34+
}
35+
2936
type MeshProjectTargetRef struct {
3037
Name string `json:"name" tfsdk:"name"`
3138
OwnedByWorkspace string `json:"ownedByWorkspace" tfsdk:"owned_by_workspace"`

0 commit comments

Comments
 (0)