Skip to content

Commit ebe959d

Browse files
authored
Merge pull request #44 from OliverEsoterik/workspace-bindings
Add additional Workspace bindings
2 parents adf9680 + 5ca393a commit ebe959d

File tree

11 files changed

+655
-14
lines changed

11 files changed

+655
-14
lines changed

client/client.go

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,15 @@ type MeshStackProviderClient struct {
3333
}
3434

3535
type endpoints struct {
36-
BuildingBlocks *url.URL `json:"meshbuildingblocks"`
37-
Projects *url.URL `json:"meshprojects"`
38-
ProjectUserBindings *url.URL `json:"meshprojectuserbindings"`
39-
ProjectGroupBindings *url.URL `json:"meshprojectgroupbindings"`
40-
Workspaces *url.URL `json:"meshworkspaces"`
41-
Tenants *url.URL `json:"meshtenants"`
42-
TagDefinitions *url.URL `json:"meshtagdefinitions"`
36+
BuildingBlocks *url.URL `json:"meshbuildingblocks"`
37+
Projects *url.URL `json:"meshprojects"`
38+
ProjectUserBindings *url.URL `json:"meshprojectuserbindings"`
39+
ProjectGroupBindings *url.URL `json:"meshprojectgroupbindings"`
40+
Workspaces *url.URL `json:"meshworkspaces"`
41+
WorkspaceUserBindings *url.URL `json:"meshworkspaceuserbindings"`
42+
WorkspaceGroupBindings *url.URL `json:"meshworkspacegroupbindings"`
43+
Tenants *url.URL `json:"meshtenants"`
44+
TagDefinitions *url.URL `json:"meshtagdefinitions"`
4345
}
4446

4547
type loginResponse struct {
@@ -60,13 +62,15 @@ func NewClient(rootUrl *url.URL, apiKey string, apiSecret string) (*MeshStackPro
6062

6163
// TODO: lookup endpoints
6264
client.endpoints = endpoints{
63-
BuildingBlocks: rootUrl.JoinPath(apiMeshObjectsRoot, "meshbuildingblocks"),
64-
Projects: rootUrl.JoinPath(apiMeshObjectsRoot, "meshprojects"),
65-
ProjectUserBindings: rootUrl.JoinPath(apiMeshObjectsRoot, "meshprojectbindings", "userbindings"),
66-
ProjectGroupBindings: rootUrl.JoinPath(apiMeshObjectsRoot, "meshprojectbindings", "groupbindings"),
67-
Workspaces: rootUrl.JoinPath(apiMeshObjectsRoot, "meshworkspaces"),
68-
Tenants: rootUrl.JoinPath(apiMeshObjectsRoot, "meshtenants"),
69-
TagDefinitions: rootUrl.JoinPath(apiMeshObjectsRoot, "meshtagdefinitions"),
65+
BuildingBlocks: rootUrl.JoinPath(apiMeshObjectsRoot, "meshbuildingblocks"),
66+
Projects: rootUrl.JoinPath(apiMeshObjectsRoot, "meshprojects"),
67+
ProjectUserBindings: rootUrl.JoinPath(apiMeshObjectsRoot, "meshprojectbindings", "userbindings"),
68+
ProjectGroupBindings: rootUrl.JoinPath(apiMeshObjectsRoot, "meshprojectbindings", "groupbindings"),
69+
Workspaces: rootUrl.JoinPath(apiMeshObjectsRoot, "meshworkspaces"),
70+
WorkspaceUserBindings: rootUrl.JoinPath(apiMeshObjectsRoot, "meshworkspacebindings", "userbindings"),
71+
WorkspaceGroupBindings: rootUrl.JoinPath(apiMeshObjectsRoot, "meshworkspacebindings", "groupbindings"),
72+
Tenants: rootUrl.JoinPath(apiMeshObjectsRoot, "meshtenants"),
73+
TagDefinitions: rootUrl.JoinPath(apiMeshObjectsRoot, "meshtagdefinitions"),
7074
}
7175

7276
return client, nil

client/workspace_binding.go

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package client
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
"fmt"
7+
"io"
8+
"net/http"
9+
"net/url"
10+
)
11+
12+
type MeshWorkspaceBinding struct {
13+
ApiVersion string `json:"apiVersion" tfsdk:"api_version"`
14+
Kind string `json:"kind" tfsdk:"kind"`
15+
Metadata MeshWorkspaceBindingMetadata `json:"metadata" tfsdk:"metadata"`
16+
RoleRef MeshWorkspaceRoleRef `json:"roleRef" tfsdk:"role_ref"`
17+
TargetRef MeshWorkspaceTargetRef `json:"targetRef" tfsdk:"target_ref"`
18+
Subject MeshWorkspaceSubject `json:"subject" tfsdk:"subject"`
19+
}
20+
21+
type MeshWorkspaceBindingMetadata struct {
22+
Name string `json:"name" tfsdk:"name"`
23+
}
24+
25+
type MeshWorkspaceRoleRef struct {
26+
Name string `json:"name" tfsdk:"name"`
27+
}
28+
29+
type MeshWorkspaceTargetRef struct {
30+
Name string `json:"name" tfsdk:"name"`
31+
}
32+
33+
type MeshWorkspaceSubject struct {
34+
Name string `json:"name" tfsdk:"name"`
35+
}
36+
37+
func (c *MeshStackProviderClient) readWorkspaceBinding(name string, contentType string) (*MeshWorkspaceBinding, error) {
38+
var targetUrl *url.URL
39+
switch contentType {
40+
case CONTENT_TYPE_WORKSPACE_USER_BINDING:
41+
targetUrl = c.urlForWorkspaceUserBinding(name)
42+
43+
case CONTENT_TYPE_WORKSPACE_GROUP_BINDING:
44+
targetUrl = c.urlForWorkspaceGroupBinding(name)
45+
46+
default:
47+
return nil, fmt.Errorf("Unexpected content type: %s", contentType)
48+
}
49+
50+
req, err := http.NewRequest("GET", targetUrl.String(), nil)
51+
if err != nil {
52+
return nil, err
53+
}
54+
req.Header.Set("Accept", contentType)
55+
56+
res, err := c.doAuthenticatedRequest(req)
57+
if err != nil {
58+
return nil, err
59+
}
60+
61+
defer res.Body.Close()
62+
63+
data, err := io.ReadAll(res.Body)
64+
if err != nil {
65+
return nil, err
66+
}
67+
68+
if res.StatusCode == 404 {
69+
return nil, nil
70+
}
71+
72+
if !isSuccessHTTPStatus(res) {
73+
return nil, fmt.Errorf("unexpected status code: %d, %s", res.StatusCode, data)
74+
}
75+
76+
var binding MeshWorkspaceBinding
77+
err = json.Unmarshal(data, &binding)
78+
if err != nil {
79+
return nil, err
80+
}
81+
82+
return &binding, nil
83+
}
84+
85+
func (c *MeshStackProviderClient) createWorkspaceBinding(binding *MeshWorkspaceBinding, contentType string) (*MeshWorkspaceBinding, error) {
86+
var targetUrl *url.URL
87+
switch contentType {
88+
case CONTENT_TYPE_WORKSPACE_USER_BINDING:
89+
targetUrl = c.endpoints.WorkspaceUserBindings
90+
91+
case CONTENT_TYPE_WORKSPACE_GROUP_BINDING:
92+
targetUrl = c.endpoints.WorkspaceGroupBindings
93+
94+
default:
95+
return nil, fmt.Errorf("Unexpected content type: %s", contentType)
96+
}
97+
98+
payload, err := json.Marshal(binding)
99+
if err != nil {
100+
return nil, err
101+
}
102+
103+
req, err := http.NewRequest("POST", targetUrl.String(), bytes.NewBuffer(payload))
104+
if err != nil {
105+
return nil, err
106+
}
107+
req.Header.Set("Content-Type", contentType)
108+
req.Header.Set("Accept", contentType)
109+
110+
res, err := c.doAuthenticatedRequest(req)
111+
if err != nil {
112+
return nil, err
113+
}
114+
115+
defer res.Body.Close()
116+
117+
data, err := io.ReadAll(res.Body)
118+
if err != nil {
119+
return nil, err
120+
}
121+
122+
if !isSuccessHTTPStatus(res) {
123+
return nil, fmt.Errorf("unexpected status code: %d, %s", res.StatusCode, data)
124+
}
125+
126+
var createdBinding MeshWorkspaceBinding
127+
err = json.Unmarshal(data, &createdBinding)
128+
if err != nil {
129+
return nil, err
130+
}
131+
132+
return &createdBinding, nil
133+
}

client/workspace_group_binding.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package client
2+
3+
import (
4+
"net/url"
5+
)
6+
7+
const CONTENT_TYPE_WORKSPACE_GROUP_BINDING = "application/vnd.meshcloud.api.meshworkspacegroupbinding.v2.hal+json"
8+
9+
type MeshWorkspaceGroupBinding = MeshWorkspaceBinding
10+
11+
func (c *MeshStackProviderClient) urlForWorkspaceGroupBinding(name string) *url.URL {
12+
return c.endpoints.WorkspaceGroupBindings.JoinPath(name)
13+
}
14+
15+
func (c *MeshStackProviderClient) ReadWorkspaceGroupBinding(name string) (*MeshWorkspaceGroupBinding, error) {
16+
return c.readWorkspaceBinding(name, CONTENT_TYPE_WORKSPACE_GROUP_BINDING)
17+
}
18+
19+
func (c *MeshStackProviderClient) CreateWorkspaceGroupBinding(binding *MeshWorkspaceGroupBinding) (*MeshWorkspaceGroupBinding, error) {
20+
return c.createWorkspaceBinding(binding, CONTENT_TYPE_WORKSPACE_GROUP_BINDING)
21+
}
22+
23+
func (c *MeshStackProviderClient) DeleteWorkspaceGroupBinding(name string) error {
24+
targetUrl := c.urlForWorkspaceGroupBinding(name)
25+
return c.deleteMeshObject(*targetUrl, 204)
26+
}

client/workspace_user_binding.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package client
2+
3+
import (
4+
"net/url"
5+
)
6+
7+
const CONTENT_TYPE_WORKSPACE_USER_BINDING = "application/vnd.meshcloud.api.meshworkspaceuserbinding.v2.hal+json"
8+
9+
type MeshWorkspaceUserBinding = MeshWorkspaceBinding
10+
11+
func (c *MeshStackProviderClient) urlForWorkspaceUserBinding(name string) *url.URL {
12+
return c.endpoints.WorkspaceUserBindings.JoinPath(name)
13+
}
14+
15+
func (c *MeshStackProviderClient) ReadWorkspaceUserBinding(name string) (*MeshWorkspaceUserBinding, error) {
16+
return c.readWorkspaceBinding(name, CONTENT_TYPE_WORKSPACE_USER_BINDING)
17+
}
18+
19+
func (c *MeshStackProviderClient) CreateWorkspaceUserBinding(binding *MeshWorkspaceUserBinding) (*MeshWorkspaceUserBinding, error) {
20+
return c.createWorkspaceBinding(binding, CONTENT_TYPE_WORKSPACE_USER_BINDING)
21+
}
22+
23+
func (c *MeshStackProviderClient) DeleteWorkspaceUserBinding(name string) error {
24+
targetUrl := c.urlForWorkspaceUserBinding(name)
25+
return c.deleteMeshObject(*targetUrl, 204)
26+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# import via workspace binding name
2+
terraform import 'meshstack_workspace_group_binding.example' 'my-binding-name'
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
resource "meshstack_workspace_group_binding" "example" {
2+
metadata = {
3+
name = "this-is-an-example"
4+
}
5+
6+
role_ref = {
7+
name = "Workspace Member"
8+
}
9+
10+
target_ref = {
11+
name = "my-workspace"
12+
}
13+
14+
subject = {
15+
name = "my-user-group"
16+
}
17+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# import via workspace binding name
2+
terraform import 'meshstack_workspace_user_binding.example' 'my-binding-name'
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
resource "meshstack_workspace_user_binding" "example" {
2+
metadata = {
3+
name = "this-is-an-example"
4+
}
5+
6+
role_ref = {
7+
name = "Workspace Member"
8+
}
9+
10+
target_ref = {
11+
name = "my-workspace"
12+
}
13+
14+
subject = {
15+
16+
}
17+
}

internal/provider/provider.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ func (p *MeshStackProvider) Resources(ctx context.Context) []func() resource.Res
108108
NewTenantV4Resource,
109109
NewProjectUserBindingResource,
110110
NewProjectGroupBindingResource,
111+
NewWorkspaceUserBindingResource,
112+
NewWorkspaceGroupBindingResource,
111113
NewWorkspaceResource,
112114
NewBuildingBlockResource,
113115
NewBuildingBlockV2Resource,

0 commit comments

Comments
 (0)