Skip to content

Commit 10b8cf9

Browse files
committed
Introduced dynatrace_application_detection_rule_v2 resource
1 parent d826080 commit 10b8cf9

File tree

12 files changed

+382
-0
lines changed

12 files changed

+382
-0
lines changed

.github/workflows/tests.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,6 +1242,17 @@ jobs:
12421242
IAM_ACCOUNT_ID: ${{ secrets.IAM_ACCOUNT_ID }}
12431243
IAM_CLIENT_SECRET: ${{ secrets.IAM_CLIENT_SECRET }}
12441244
run: go test -v ./dynatrace/api/builtin/ownership/teams
1245+
- name: TestApplicationDetectionRules
1246+
env:
1247+
GOPROXY: "https://proxy.golang.org"
1248+
TF_ACC: true
1249+
DYNATRACE_DEBUG: true
1250+
DYNATRACE_ENV_URL: ${{ secrets.DYNATRACE_ENV_URL }}
1251+
DYNATRACE_API_TOKEN: ${{ secrets.DYNATRACE_API_TOKEN }}
1252+
IAM_CLIENT_ID: ${{ secrets.IAM_CLIENT_ID }}
1253+
IAM_ACCOUNT_ID: ${{ secrets.IAM_ACCOUNT_ID }}
1254+
IAM_CLIENT_SECRET: ${{ secrets.IAM_CLIENT_SECRET }}
1255+
run: go test -v ./dynatrace/api/builtin/rum/web/appdetection
12451256
# - name: TestLogCustomSource
12461257
# env:
12471258
# GOPROXY: "https://proxy.golang.org"
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
{
2+
"allowedScopes": [
3+
"environment"
4+
],
5+
"description": "Define new applications for Real User Monitoring (RUM) using [application detection rules](https://dt-url.net/wb3f0pfr), check how your existing rules map to your applications.\n\n## Define application detection rules\n\nBy default, Dynatrace associates all your monitoring data with a [placeholder application](/#uemapplications/uemappmetrics;uemapplicationId=APPLICATION-EA7C4B59F27D43EB). Define your own detection rules for grouping your monitoring data into distinct applications in Dynatrace.\n\n",
6+
"displayName": "Application detection",
7+
"documentation": "\n\nIf you haven't done so already, [deploy OneAgent](/#install). After the deployment [RUM](https://dt-url.net/1n2b0prq) is enabled by default for all web applications that are auto-detected by OneAgent. OneAgent [automatically injects](https://dt-url.net/kp5f0p5z) a JavaScript code snippet into the HTML of all the pages of your monitored web applications so that it can capture monitoring data and ensure end-to-end monitoring visibility.\n\n* Rules are applied sequentially, with rules at the top taking priority over lower rules.\n\n* [Not seeing your applications or RUM data?](https://dt-url.net/kl2a0pm4)\n\n* More details on [defining your web application](https://dt-url.net/r63b0pgq).\n\n## Examples\nGiven a set of URLs\u0026#58;\n* http\u0026#58;//www\u0026#46;mybookshop\u0026#46;com/about\n* http\u0026#58;//checkout\u0026#46;mybookshop\u0026#46;com/proceed\n* http\u0026#58;//mybook\u0026#46;shop\u0026#46;com/about/index\u0026#46;php\n* http\u0026#58;//www\u0026#46;this-is-mybookshop\u0026#46;com/about/index\u0026#46;php\n\nThe rule *Domain (host) contains* **mybook** matches against\u0026#58;\n* http\u0026#58;//www\u0026#46;**mybook**shop\u0026#46;com/about\n* http\u0026#58;//checkout\u0026#46;**mybook**shop\u0026#46;com/proceed\n* http\u0026#58;//**mybook**\u0026#46;shop\u0026#46;com/about/index\u0026#46;php\n* http\u0026#58;//www\u0026#46;this-is-**mybook**shop\u0026#46;com/about/index\u0026#46;php\n\nThe rule *Domain (host) ends with* **shop\u0026#46;com** matches against\u0026#58;\n* http\u0026#58;//www\u0026#46;mybook**shop\u0026#46;com**/about\n* http\u0026#58;//checkout\u0026#46;mybook**shop\u0026#46;com**/proceed\n* http\u0026#58;//mybook\u0026#46;**shop\u0026#46;com**/about/index\u0026#46;php\n* http\u0026#58;//www\u0026#46;this-is-mybook**shop\u0026#46;com**/about/index\u0026#46;php\n\nThe rule *Domain (host) equals* **www\u0026#46;mybookshop\u0026#46;com** matches against\u0026#58;\n* http\u0026#58;//**www\u0026#46;mybookshop\u0026#46;com**/about/index\u0026#46;php\n\nThe rule *Domain (host) matches* **mybookshop\u0026#46;com** matches against\u0026#58;\n* http\u0026#58;//www\u0026#46;**mybookshop\u0026#46;com**/about\n* http\u0026#58;//checkout\u0026#46;**mybookshop\u0026#46;com**/proceed\n\nThe rule *Domain (host) starts with* **checkout** matches against\u0026#58;\n* http\u0026#58;//**checkout**\u0026#46;mybookshop\u0026#46;com/proceed\n\nThe rule *URL contains* **mybookshop\u0026#46;com/about** matches against\u0026#58;\n* http\u0026#58;//www\u0026#46;**mybookshop\u0026#46;com/about**\n* http\u0026#58;//www\u0026#46;this-is-**mybookshop\u0026#46;com/about**/index\u0026#46;php\n\nThe rule *URL ends with* **about/index\u0026#46;php** matches against\u0026#58;\n* http\u0026#58;//mybook\u0026#46;shop\u0026#46;com/**about/index\u0026#46;php**\n* http\u0026#58;//www\u0026#46;this-is-mybookshop\u0026#46;com/**about/index\u0026#46;php**\n\nThe rule *URL equals* **http\u0026#58;//www\u0026#46;mybookshop\u0026#46;com/about** matches against\u0026#58;\n* **http\u0026#58;//www\u0026#46;mybookshop\u0026#46;com/about**\n\nThe rule *URL starts with* **http\u0026#58;//www\u0026#46;mybookshop\u0026#46;com** matches against\u0026#58;\n* **http\u0026#58;//www\u0026#46;mybookshop\u0026#46;com**/about",
8+
"dynatrace": "1",
9+
"enums": {
10+
"Matcher": {
11+
"description": "",
12+
"displayName": "Matcher",
13+
"documentation": "",
14+
"items": [
15+
{
16+
"displayName": "Domain (host) contains",
17+
"value": "DOMAIN_CONTAINS"
18+
},
19+
{
20+
"displayName": "Domain (host) ends with",
21+
"value": "DOMAIN_ENDS_WITH"
22+
},
23+
{
24+
"displayName": "Domain (host) equals",
25+
"value": "DOMAIN_EQUALS"
26+
},
27+
{
28+
"displayName": "Domain (host) matches",
29+
"value": "DOMAIN_MATCHES"
30+
},
31+
{
32+
"displayName": "Domain (host) starts with",
33+
"value": "DOMAIN_STARTS_WITH"
34+
},
35+
{
36+
"displayName": "URL contains",
37+
"value": "URL_CONTAINS"
38+
},
39+
{
40+
"displayName": "URL ends with",
41+
"value": "URL_ENDS_WITH"
42+
},
43+
{
44+
"displayName": "URL equals",
45+
"value": "URL_EQUALS"
46+
},
47+
{
48+
"displayName": "URL starts with",
49+
"value": "URL_STARTS_WITH"
50+
}
51+
],
52+
"type": "enum"
53+
}
54+
},
55+
"maxObjects": 1000,
56+
"multiObject": true,
57+
"ordered": true,
58+
"properties": {
59+
"applicationId": {
60+
"constraints": [
61+
{
62+
"maxLength": 500,
63+
"minLength": 1,
64+
"type": "LENGTH"
65+
},
66+
{
67+
"customMessage": "Invalid applicationId",
68+
"customValidatorId": "rumAppDetectionAppIdValidator",
69+
"type": "CUSTOM_VALIDATOR_REF"
70+
}
71+
],
72+
"default": "",
73+
"description": "Select an existing application or create a new one.",
74+
"displayName": "Application",
75+
"documentation": "",
76+
"maxObjects": 1,
77+
"modificationPolicy": "DEFAULT",
78+
"nullable": false,
79+
"subType": "rum_app_detection_app_picker",
80+
"type": "text"
81+
},
82+
"matcher": {
83+
"default": "DOMAIN_MATCHES",
84+
"description": "",
85+
"displayName": "Matcher",
86+
"documentation": "",
87+
"maxObjects": 1,
88+
"modificationPolicy": "DEFAULT",
89+
"nullable": false,
90+
"type": {
91+
"$ref": "#/enums/Matcher"
92+
}
93+
},
94+
"pattern": {
95+
"constraints": [
96+
{
97+
"minLength": 1,
98+
"type": "LENGTH"
99+
}
100+
],
101+
"default": "",
102+
"description": "",
103+
"displayName": "Pattern",
104+
"documentation": "",
105+
"maxObjects": 1,
106+
"modificationPolicy": "DEFAULT",
107+
"nullable": false,
108+
"type": "text"
109+
}
110+
},
111+
"schemaGroups": [
112+
"group:web-and-mobile-monitoring.web-applications",
113+
"group:web-and-mobile-monitoring"
114+
],
115+
"schemaId": "builtin:rum.web.app-detection",
116+
"types": {},
117+
"version": "2.0.1"
118+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
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 appdetection
19+
20+
import (
21+
"fmt"
22+
23+
"github.com/dynatrace-oss/terraform-provider-dynatrace/dynatrace/api"
24+
appdetection "github.com/dynatrace-oss/terraform-provider-dynatrace/dynatrace/api/builtin/rum/web/appdetection/settings"
25+
"github.com/dynatrace-oss/terraform-provider-dynatrace/dynatrace/settings"
26+
"github.com/dynatrace-oss/terraform-provider-dynatrace/dynatrace/settings/services/settings20"
27+
)
28+
29+
const SchemaVersion = "2.0.1"
30+
const SchemaID = "builtin:rum.web.app-detection"
31+
32+
func Service(credentials *settings.Credentials) settings.CRUDService[*appdetection.Settings] {
33+
return settings20.Service(credentials, SchemaID, SchemaVersion, &settings20.ServiceOptions[*appdetection.Settings]{Duplicates: Duplicates})
34+
}
35+
36+
func Duplicates(service settings.RService[*appdetection.Settings], v *appdetection.Settings) (*api.Stub, error) {
37+
if settings.RejectDuplicate("dynatrace_application_detection_rule_v2") {
38+
var err error
39+
var stubs api.Stubs
40+
if stubs, err = service.List(); err != nil {
41+
return nil, err
42+
}
43+
for _, stub := range stubs {
44+
config := stub.Value.(*appdetection.Settings)
45+
if v.Matcher == config.Matcher && v.Pattern == config.Pattern {
46+
return nil, fmt.Errorf("Application detection rule with filter already exists")
47+
}
48+
}
49+
} else if settings.HijackDuplicate("dynatrace_application_detection_rule_v2") {
50+
var err error
51+
var stubs api.Stubs
52+
if stubs, err = service.List(); err != nil {
53+
return nil, err
54+
}
55+
for _, stub := range stubs {
56+
config := stub.Value.(*appdetection.Settings)
57+
if v.Matcher == config.Matcher && v.Pattern == config.Pattern {
58+
return stub, nil
59+
}
60+
}
61+
}
62+
return nil, nil
63+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
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 appdetection_test
19+
20+
import (
21+
"testing"
22+
23+
"github.com/dynatrace-oss/terraform-provider-dynatrace/dynatrace/api/builtin/rum/web/appdetection"
24+
"github.com/dynatrace-oss/terraform-provider-dynatrace/dynatrace/testing/api"
25+
)
26+
27+
func TestApplicationDetectionRules(t *testing.T) {
28+
api.TestService(t, appdetection.Service)
29+
}
30+
31+
func TestAccApplicationDetectionRules(t *testing.T) {
32+
api.TestAcc(t)
33+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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 appdetection
19+
20+
type Matcher string
21+
22+
var Matchers = struct {
23+
DomainContains Matcher
24+
DomainEndsWith Matcher
25+
DomainEquals Matcher
26+
DomainMatches Matcher
27+
DomainStartsWith Matcher
28+
UrlContains Matcher
29+
UrlEndsWith Matcher
30+
UrlEquals Matcher
31+
UrlStartsWith Matcher
32+
}{
33+
"DOMAIN_CONTAINS",
34+
"DOMAIN_ENDS_WITH",
35+
"DOMAIN_EQUALS",
36+
"DOMAIN_MATCHES",
37+
"DOMAIN_STARTS_WITH",
38+
"URL_CONTAINS",
39+
"URL_ENDS_WITH",
40+
"URL_EQUALS",
41+
"URL_STARTS_WITH",
42+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
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 appdetection
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 Settings struct {
26+
ApplicationID string `json:"applicationId"` // Select an existing application or create a new one.
27+
Matcher Matcher `json:"matcher"` // Possible Values: `DOMAIN_CONTAINS`, `DOMAIN_ENDS_WITH`, `DOMAIN_EQUALS`, `DOMAIN_MATCHES`, `DOMAIN_STARTS_WITH`, `URL_CONTAINS`, `URL_ENDS_WITH`, `URL_EQUALS`, `URL_STARTS_WITH`
28+
Pattern string `json:"pattern"` // Pattern
29+
}
30+
31+
func (me *Settings) Name() string {
32+
return me.ApplicationID
33+
}
34+
35+
func (me *Settings) Schema() map[string]*schema.Schema {
36+
return map[string]*schema.Schema{
37+
"application_id": {
38+
Type: schema.TypeString,
39+
Description: "Select an existing application or create a new one.",
40+
Required: true,
41+
},
42+
"matcher": {
43+
Type: schema.TypeString,
44+
Description: "Possible Values: `DOMAIN_CONTAINS`, `DOMAIN_ENDS_WITH`, `DOMAIN_EQUALS`, `DOMAIN_MATCHES`, `DOMAIN_STARTS_WITH`, `URL_CONTAINS`, `URL_ENDS_WITH`, `URL_EQUALS`, `URL_STARTS_WITH`",
45+
Required: true,
46+
},
47+
"pattern": {
48+
Type: schema.TypeString,
49+
Description: "Pattern",
50+
Required: true,
51+
},
52+
}
53+
}
54+
55+
func (me *Settings) MarshalHCL(properties hcl.Properties) error {
56+
return properties.EncodeAll(map[string]any{
57+
"application_id": me.ApplicationID,
58+
"matcher": me.Matcher,
59+
"pattern": me.Pattern,
60+
})
61+
}
62+
63+
func (me *Settings) UnmarshalHCL(decoder hcl.Decoder) error {
64+
return decoder.DecodeAll(map[string]any{
65+
"application_id": &me.ApplicationID,
66+
"matcher": &me.Matcher,
67+
"pattern": &me.Pattern,
68+
})
69+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"applicationId": "APPLICATION-1234567890000000",
3+
"matcher": "DOMAIN_MATCHES",
4+
"pattern": "TerraformTest"
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
resource "dynatrace_application_detection_rule_v2" "#name#" {
2+
application_id = "APPLICATION-1234567890000000"
3+
matcher = "DOMAIN_MATCHES"
4+
pattern = "TerraformTest"
5+
}

dynatrace/export/enums.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ var ResourceTypes = struct {
255255
OneAgentUpdates ResourceType
256256
OwnershipTeams ResourceType
257257
LogCustomSource ResourceType
258+
ApplicationDetectionV2 ResourceType
258259
}{
259260
"dynatrace_autotag",
260261
"dynatrace_custom_service",
@@ -455,6 +456,7 @@ var ResourceTypes = struct {
455456
"dynatrace_oneagent_updates",
456457
"dynatrace_ownership_teams",
457458
"dynatrace_log_custom_source",
459+
"dynatrace_application_detection_rule_v2",
458460
}
459461

460462
type ResourceStatus string

0 commit comments

Comments
 (0)