Skip to content

Commit ac527ab

Browse files
committed
Introduced dynatrace_segments resource
1 parent c466952 commit ac527ab

File tree

14 files changed

+1065
-0
lines changed

14 files changed

+1065
-0
lines changed

.github/workflows/tests.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,19 @@ jobs:
6060
DT_CLIENT_SECRET: ${{ secrets.DT_CLIENT_SECRET }}
6161
DT_ACCOUNT_ID: ${{ secrets.DT_ACCOUNT_ID }}
6262
run: go test -v ./dynatrace/api/automation/scheduling_rules
63+
- name: TestAccSegments
64+
if: success() || failure()
65+
env:
66+
GOPROXY: "https://proxy.golang.org"
67+
TF_ACC: true
68+
DYNATRACE_DEBUG: true
69+
DT_NO_REPAIR_INPUT: false
70+
DYNATRACE_ENV_URL: ${{ secrets.DYNATRACE_ENV_URL }}
71+
DYNATRACE_API_TOKEN: ${{ secrets.DYNATRACE_API_TOKEN }}
72+
DT_CLIENT_ID: ${{ secrets.DT_CLIENT_ID }}
73+
DT_CLIENT_SECRET: ${{ secrets.DT_CLIENT_SECRET }}
74+
DT_ACCOUNT_ID: ${{ secrets.DT_ACCOUNT_ID }}
75+
run: go test -v ./dynatrace/api/grail/segments
6376
- name: TestAccWorkflows
6477
if: success() || failure()
6578
env:
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
/**
2+
* @license
3+
* Copyright 2020 Dynatrace LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package segments
19+
20+
import (
21+
"context"
22+
"encoding/json"
23+
24+
"github.com/dynatrace-oss/terraform-provider-dynatrace/dynatrace/api"
25+
"github.com/dynatrace-oss/terraform-provider-dynatrace/dynatrace/rest"
26+
"github.com/dynatrace-oss/terraform-provider-dynatrace/dynatrace/settings"
27+
"github.com/dynatrace-oss/terraform-provider-dynatrace/provider/logging"
28+
segmentsapi "github.com/dynatrace/dynatrace-configuration-as-code-core/api"
29+
"github.com/dynatrace/dynatrace-configuration-as-code-core/clients"
30+
segmentsclient "github.com/dynatrace/dynatrace-configuration-as-code-core/clients/segments"
31+
"golang.org/x/oauth2/clientcredentials"
32+
33+
"github.com/dynatrace-oss/terraform-provider-dynatrace/dynatrace/api/automation/httplog"
34+
segments "github.com/dynatrace-oss/terraform-provider-dynatrace/dynatrace/api/grail/segments/settings"
35+
)
36+
37+
func Service(credentials *settings.Credentials) settings.CRUDService[*segments.Segment] {
38+
return &service{credentials}
39+
}
40+
41+
type service struct {
42+
credentials *settings.Credentials
43+
}
44+
45+
func (me *service) client(ctx context.Context) *segmentsclient.Client {
46+
httplog.InstallRoundTripper()
47+
48+
clientsFactory := clients.Factory().
49+
WithPlatformURL(me.credentials.Automation.EnvironmentURL).
50+
WithOAuthCredentials(clientcredentials.Config{
51+
ClientID: me.credentials.Automation.ClientID,
52+
ClientSecret: me.credentials.Automation.ClientSecret,
53+
TokenURL: me.credentials.Automation.TokenURL,
54+
}).
55+
WithUserAgent("Dynatrace Terraform Provider")
56+
57+
segmentClient, _ := clientsFactory.SegmentsClient(ctx)
58+
return segmentClient
59+
}
60+
61+
func (me *service) Get(ctx context.Context, id string, v *segments.Segment) (err error) {
62+
response, err := me.client(ctx).Get(ctx, id)
63+
if err != nil {
64+
if apiError, ok := err.(segmentsapi.APIError); ok {
65+
return rest.Error{Code: apiError.StatusCode, Message: apiError.Error()}
66+
}
67+
return err
68+
}
69+
70+
return json.Unmarshal(response.Data, &v)
71+
}
72+
73+
func (me *service) SchemaID() string {
74+
return "storage:filter-segments"
75+
}
76+
77+
type SegmentStub struct {
78+
UID string `json:"uid"`
79+
Name string `json:"name"`
80+
}
81+
82+
func (me *service) List(ctx context.Context) (api.Stubs, error) {
83+
listResponse, err := me.client(ctx).List(ctx)
84+
if err != nil {
85+
if apiError, ok := err.(segmentsapi.APIError); ok {
86+
return nil, rest.Error{Code: apiError.StatusCode, Message: apiError.Error()}
87+
}
88+
return nil, err
89+
}
90+
var segments []SegmentStub
91+
if err := json.Unmarshal(listResponse.Data, &segments); err != nil {
92+
return nil, err
93+
}
94+
var stubs api.Stubs
95+
for _, segment := range segments {
96+
stubs = append(stubs, &api.Stub{ID: segment.UID, Name: segment.Name})
97+
}
98+
99+
return stubs, nil
100+
}
101+
102+
func (me *service) Validate(_ *segments.Segment) error {
103+
return nil // no endpoint for that
104+
}
105+
106+
func (me *service) Create(ctx context.Context, v *segments.Segment) (stub *api.Stub, err error) {
107+
var data []byte
108+
if data, err = json.Marshal(v); err != nil {
109+
return nil, err
110+
}
111+
logging.File.Println(string(data))
112+
response, err := me.client(ctx).Create(ctx, data)
113+
if err != nil {
114+
if apiError, ok := err.(segmentsapi.APIError); ok {
115+
return nil, rest.Error{Code: apiError.StatusCode, Message: apiError.Error()}
116+
}
117+
return nil, err
118+
}
119+
120+
var segmentStub SegmentStub
121+
if err := json.Unmarshal(response.Data, &segmentStub); err != nil {
122+
return nil, err
123+
}
124+
125+
return &api.Stub{Name: v.Name, ID: segmentStub.UID}, nil
126+
}
127+
128+
func (me *service) Update(ctx context.Context, id string, v *segments.Segment) (err error) {
129+
var data []byte
130+
if data, err = json.Marshal(v); err != nil {
131+
return err
132+
}
133+
134+
_, err = me.client(ctx).Update(ctx, id, data)
135+
if err != nil {
136+
if apiError, ok := err.(segmentsapi.APIError); ok {
137+
return rest.Error{Code: apiError.StatusCode, Message: apiError.Error()}
138+
}
139+
return err
140+
}
141+
142+
return nil
143+
}
144+
145+
func (me *service) Delete(ctx context.Context, id string) error {
146+
_, err := me.client(ctx).Delete(ctx, id)
147+
if err != nil {
148+
if apiError, ok := err.(segmentsapi.APIError); ok {
149+
return rest.Error{Code: apiError.StatusCode, Message: apiError.Error()}
150+
}
151+
return err
152+
}
153+
154+
return nil
155+
}
156+
157+
func (me *service) New() *segments.Segment {
158+
return new(segments.Segment)
159+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* @license
3+
* Copyright 2020 Dynatrace LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package segments_test
19+
20+
import (
21+
"testing"
22+
23+
"github.com/dynatrace-oss/terraform-provider-dynatrace/dynatrace/testing/api"
24+
)
25+
26+
func TestAccSegments(t *testing.T) {
27+
api.TestAcc(t)
28+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/**
2+
* @license
3+
* Copyright 2020 Dynatrace LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package segments
19+
20+
import (
21+
"github.com/dynatrace-oss/terraform-provider-dynatrace/terraform/hcl"
22+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
23+
)
24+
25+
type Includes []*Items
26+
27+
func (me *Includes) Schema() map[string]*schema.Schema {
28+
return map[string]*schema.Schema{
29+
"items": {
30+
Type: schema.TypeSet,
31+
Description: "TODO: No documentation available",
32+
MaxItems: 20,
33+
Optional: true,
34+
Elem: &schema.Resource{Schema: new(Items).Schema()},
35+
},
36+
}
37+
38+
}
39+
40+
func (me Includes) MarshalHCL(properties hcl.Properties) error {
41+
return properties.EncodeSlice("items", me)
42+
}
43+
44+
func (me *Includes) UnmarshalHCL(decoder hcl.Decoder) error {
45+
return decoder.DecodeSlice("items", me)
46+
}
47+
48+
type Items struct {
49+
Filter string `json:"filter"`
50+
DataObject string `json:"dataObject"`
51+
ApplyTo []string `json:"applyTo,omitempty"`
52+
Relationship *Relationship `json:"relationship,omitempty"`
53+
}
54+
55+
func (me *Items) Schema() map[string]*schema.Schema {
56+
return map[string]*schema.Schema{
57+
"filter": {
58+
Type: schema.TypeString,
59+
Description: "Data will be filtered by this value",
60+
Required: true,
61+
ValidateDiagFunc: ValidateMaxLength(10000),
62+
},
63+
"data_object": {
64+
Type: schema.TypeString,
65+
Description: "The data object that the filter will be applied to. Use '_all_data_object' to apply it to all dataObjects",
66+
Required: true,
67+
ValidateDiagFunc: ValidateMaxLength(500),
68+
},
69+
"apply_to": {
70+
Type: schema.TypeSet,
71+
Description: "[Experimental] The tables that the entity-filter will be applied to`",
72+
Optional: true,
73+
Elem: &schema.Schema{Type: schema.TypeString},
74+
},
75+
"relationship": {
76+
Type: schema.TypeList,
77+
Description: "[Experimental] The relationship of an include which has to be be specified when the data object is an entity view",
78+
MinItems: 1,
79+
MaxItems: 1,
80+
Optional: true,
81+
Elem: &schema.Resource{Schema: new(Relationship).Schema()},
82+
},
83+
}
84+
}
85+
86+
func (me *Items) MarshalHCL(properties hcl.Properties) error {
87+
return properties.EncodeAll(map[string]any{
88+
"filter": me.Filter,
89+
"data_object": me.DataObject,
90+
"apply_to": me.ApplyTo,
91+
"relationship": me.Relationship,
92+
})
93+
}
94+
95+
func (me *Items) UnmarshalHCL(decoder hcl.Decoder) error {
96+
return decoder.DecodeAll(map[string]any{
97+
"filter": &me.Filter,
98+
"data_object": &me.DataObject,
99+
"apply_to": &me.ApplyTo,
100+
"relationship": &me.Relationship,
101+
})
102+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/**
2+
* @license
3+
* Copyright 2020 Dynatrace LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package segments
19+
20+
import (
21+
"github.com/dynatrace-oss/terraform-provider-dynatrace/terraform/hcl"
22+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
23+
)
24+
25+
type Relationship struct {
26+
Name string `json:"name"`
27+
Target string `json:"target"`
28+
}
29+
30+
func (me *Relationship) Schema() map[string]*schema.Schema {
31+
return map[string]*schema.Schema{
32+
"name": {
33+
Type: schema.TypeString,
34+
Description: "Name of the relationship",
35+
Required: true,
36+
},
37+
"target": {
38+
Type: schema.TypeString,
39+
Description: "Target of the relationship",
40+
Required: true,
41+
},
42+
}
43+
}
44+
45+
func (me *Relationship) MarshalHCL(properties hcl.Properties) error {
46+
return properties.EncodeAll(map[string]any{
47+
"name": me.Name,
48+
"target": me.Target,
49+
})
50+
}
51+
52+
func (me *Relationship) UnmarshalHCL(decoder hcl.Decoder) error {
53+
return decoder.DecodeAll(map[string]any{
54+
"name": &me.Name,
55+
"target": &me.Target,
56+
})
57+
}

0 commit comments

Comments
 (0)