Skip to content

Commit 59709cc

Browse files
d0weinbergertomazpu
authored andcommitted
feat(settings): Adding settings object permission client
The main goal of this commit is to add the client code for the settings object permission handling API. This code can then be used by both, the dynatrace-configuration-as-code project and the Terraform provider.
1 parent 94fb2ef commit 59709cc

File tree

3 files changed

+1004
-0
lines changed

3 files changed

+1004
-0
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// @license
2+
// Copyright 2025 Dynatrace LLC
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package permissions
16+
17+
import (
18+
"errors"
19+
"fmt"
20+
)
21+
22+
var (
23+
ErrorMissingObjectID = errors.New("objectID cannot be empty")
24+
ErrorMissingAccessorID = errors.New("accessorID cannot be empty")
25+
ErrorMissingAccessorType = errors.New("accessorType cannot be empty")
26+
)
27+
28+
type ErrorPermissionGet struct {
29+
Err error
30+
}
31+
32+
func (e ErrorPermissionGet) Error() string {
33+
return fmt.Sprintf("failed to get permission(s): %v", e.Err)
34+
}
35+
36+
type ErrorPermissionCreate struct {
37+
Err error
38+
}
39+
40+
func (e ErrorPermissionCreate) Error() string {
41+
return fmt.Sprintf("failed to create permission: %v", e.Err)
42+
}
43+
44+
type ErrorPermissionUpdate struct {
45+
Err error
46+
}
47+
48+
func (e ErrorPermissionUpdate) Error() string {
49+
return fmt.Sprintf("failed to update permission: %v", e.Err)
50+
}
51+
52+
type ErrorPermissionDelete struct {
53+
Err error
54+
}
55+
56+
func (e ErrorPermissionDelete) Error() string {
57+
return fmt.Sprintf("failed to delete permission object: %v", e.Err)
58+
}
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
// @license
2+
// Copyright 2025 Dynatrace LLC
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package permissions
16+
17+
import (
18+
"bytes"
19+
"context"
20+
"net/url"
21+
22+
"github.com/dynatrace/dynatrace-configuration-as-code-core/api"
23+
"github.com/dynatrace/dynatrace-configuration-as-code-core/api/rest"
24+
)
25+
26+
const endpointConfigPath = "platform/classic/environment-api/v2/settings/objects"
27+
const permissionResourcePath = "permissions"
28+
const allUsersAccessorType = "all-users"
29+
30+
type Client struct {
31+
client *rest.Client
32+
}
33+
34+
func NewClient(client *rest.Client) *Client {
35+
return &Client{client: client}
36+
}
37+
38+
func (c *Client) GetAllAccessors(ctx context.Context, objectID string) (api.Response, error) {
39+
return c.get(ctx, objectID, "", "")
40+
}
41+
42+
func (c *Client) GetAllUsersAccessor(ctx context.Context, objectID string) (api.Response, error) {
43+
return c.get(ctx, objectID, allUsersAccessorType, "")
44+
}
45+
46+
func (c *Client) GetAccessor(ctx context.Context, objectID string, accessorType string, accessorID string) (api.Response, error) {
47+
if accessorType == "" {
48+
return api.Response{}, ErrorPermissionGet{ErrorMissingAccessorType}
49+
}
50+
51+
if accessorID == "" {
52+
return api.Response{}, ErrorPermissionGet{ErrorMissingAccessorID}
53+
}
54+
55+
return c.get(ctx, objectID, accessorType, accessorID)
56+
}
57+
58+
func (c *Client) get(ctx context.Context, objectID string, accessorType string, accessorID string) (api.Response, error) {
59+
if objectID == "" {
60+
return api.Response{}, ErrorPermissionGet{ErrorMissingObjectID}
61+
}
62+
63+
path, err := url.JoinPath(endpointConfigPath, objectID, permissionResourcePath, accessorType, accessorID)
64+
if err != nil {
65+
return api.Response{}, ErrorPermissionGet{err}
66+
}
67+
68+
resp, err := c.client.GET(ctx, path, rest.RequestOptions{CustomShouldRetryFunc: rest.RetryIfTooManyRequests})
69+
70+
if err != nil {
71+
return api.Response{}, ErrorPermissionGet{err}
72+
}
73+
74+
return api.NewResponseFromHTTPResponse(resp)
75+
}
76+
77+
func (c *Client) Create(ctx context.Context, objectID string, body []byte) (api.Response, error) {
78+
if objectID == "" {
79+
return api.Response{}, ErrorPermissionCreate{ErrorMissingObjectID}
80+
}
81+
82+
path, err := url.JoinPath(endpointConfigPath, objectID, permissionResourcePath)
83+
if err != nil {
84+
return api.Response{}, ErrorPermissionCreate{err}
85+
}
86+
87+
resp, err := c.client.POST(ctx, path, bytes.NewReader(body), rest.RequestOptions{CustomShouldRetryFunc: rest.RetryIfTooManyRequests})
88+
if err != nil {
89+
return api.Response{}, ErrorPermissionCreate{err}
90+
}
91+
92+
return api.NewResponseFromHTTPResponse(resp)
93+
}
94+
95+
func (c *Client) UpdateAllUsersAccessor(ctx context.Context, objectID string, body []byte) (api.Response, error) {
96+
return c.update(ctx, objectID, allUsersAccessorType, "", body)
97+
}
98+
99+
func (c *Client) UpdateAccessor(ctx context.Context, objectID string, accessorType string, accessorID string, body []byte) (api.Response, error) {
100+
if accessorType == "" {
101+
return api.Response{}, ErrorPermissionUpdate{ErrorMissingAccessorType}
102+
}
103+
104+
if accessorID == "" {
105+
return api.Response{}, ErrorPermissionUpdate{ErrorMissingAccessorID}
106+
}
107+
108+
return c.update(ctx, objectID, accessorType, accessorID, body)
109+
}
110+
111+
func (c *Client) update(ctx context.Context, objectID string, accessorType string, accessorID string, body []byte) (api.Response, error) {
112+
if objectID == "" {
113+
return api.Response{}, ErrorPermissionUpdate{ErrorMissingObjectID}
114+
}
115+
116+
path, err := url.JoinPath(endpointConfigPath, objectID, permissionResourcePath, accessorType, accessorID)
117+
if err != nil {
118+
return api.Response{}, ErrorPermissionUpdate{err}
119+
}
120+
121+
httpResp, err := c.client.PUT(ctx, path, bytes.NewReader(body), rest.RequestOptions{CustomShouldRetryFunc: rest.RetryIfTooManyRequests})
122+
123+
if err != nil {
124+
return api.Response{}, ErrorPermissionUpdate{err}
125+
}
126+
127+
return api.NewResponseFromHTTPResponse(httpResp)
128+
}
129+
130+
func (c *Client) DeleteAllUsersAccessor(ctx context.Context, objectID string) (api.Response, error) {
131+
return c.delete(ctx, objectID, allUsersAccessorType, "")
132+
}
133+
134+
func (c *Client) DeleteAccessor(ctx context.Context, objectID string, accessorType string, accessorID string) (api.Response, error) {
135+
if accessorType == "" {
136+
return api.Response{}, ErrorPermissionDelete{ErrorMissingAccessorType}
137+
}
138+
139+
if accessorID == "" {
140+
return api.Response{}, ErrorPermissionDelete{ErrorMissingAccessorID}
141+
}
142+
143+
return c.delete(ctx, objectID, accessorType, accessorID)
144+
}
145+
146+
func (c *Client) delete(ctx context.Context, objectID string, accessorType string, accessorID string) (api.Response, error) {
147+
if objectID == "" {
148+
return api.Response{}, ErrorPermissionDelete{ErrorMissingObjectID}
149+
}
150+
151+
path, err := url.JoinPath(endpointConfigPath, objectID, permissionResourcePath, accessorType, accessorID)
152+
if err != nil {
153+
return api.Response{}, ErrorPermissionDelete{err}
154+
}
155+
156+
httpResp, err := c.client.DELETE(ctx, path, rest.RequestOptions{CustomShouldRetryFunc: rest.RetryIfTooManyRequests})
157+
158+
if err != nil {
159+
return api.Response{}, ErrorPermissionDelete{err}
160+
}
161+
162+
return api.NewResponseFromHTTPResponse(httpResp)
163+
}

0 commit comments

Comments
 (0)