Skip to content

Commit

Permalink
Update Settings based on unique key properties
Browse files Browse the repository at this point in the history
For Settings schemas with unique key constraints, these key constraints are used in addition to the external ID to identify and update an existing object.

This ensures that Settings objects are not attempted to be duplicated but are correctly found and updated.

Changes in addition to the main feature:

* test(e2e): Add test which tries to deploy settings2.0 object (span-attribute) with the same unique key but different coordinates/externalID in two different projects and checks that a single object was created and updated without error.
* refactor(client): Move all settings clients test to same file
* refactor(client): Move all config client tests to same file
* refactor(client): Move all entity client tests to same file

---------

Co-authored-by: Jure Skelin <[email protected]>
Co-authored-by: UnseenWizzard <[email protected]>
  • Loading branch information
3 people authored Jul 27, 2023
1 parent a6b9a41 commit d17d26b
Show file tree
Hide file tree
Showing 17 changed files with 1,932 additions and 1,148 deletions.
19 changes: 19 additions & 0 deletions cmd/monaco/integrationtest/v2/settings_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,25 @@ func TestOldExternalIDGetsUpdated(t *testing.T) {

}

func TestDeploySettingsWithUniqueProperties(t *testing.T) {
fs := testutils.CreateTestFileSystem()
var manifestPath = "test-resources/settings-unique-properties/manifest.yaml"
loadedManifest := integrationtest.LoadManifest(t, fs, manifestPath, "platform_env")

t.Cleanup(func() {
integrationtest.CleanupIntegrationTest(t, fs, manifestPath, loadedManifest, "")
})

cmd := runner.BuildCli(fs)
cmd.SetArgs([]string{"deploy", "-e", "platform_env", "-p", "project1", manifestPath})
err := cmd.Execute()
assert.NoError(t, err)

cmd.SetArgs([]string{"deploy", "-e", "platform_env", "-p", "project2", manifestPath})
err = cmd.Execute()
assert.NoError(t, err)
}

func createSettingsClient(t *testing.T, env manifest.EnvironmentDefinition, opts ...func(dynatraceClient *dtclient.DynatraceClient)) dtclient.SettingsClient {
oauthCredentials := auth.OauthCredentials{
ClientID: env.Auth.OAuth.ClientID.Value,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
manifestVersion: 1.0
projects:
- name: project1
- name: project2
environmentGroups:
- name: default
environments:
- name: classic_env
url:
type: environment
value: URL_ENVIRONMENT_1
auth:
token:
name: TOKEN_ENVIRONMENT_1
- name: platform_env
url:
type: environment
value: PLATFORM_URL_ENVIRONMENT_2
auth:
token:
name: TOKEN_ENVIRONMENT_2
oAuth:
clientId:
name: OAUTH_CLIENT_ID
clientSecret:
name: OAUTH_CLIENT_SECRET
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
configs:
- id: d955d9b7-9630-3be5-aca5-3715779a7282
config:
name: d955d9b7-9630-3be5-aca5-3715779a7282
template: d955d9b7-9630-3be5-aca5-3715779a7282.json
skip: false
type:
settings:
schema: builtin:monitoring.slo
schemaVersion: 6.0.12
scope: environment
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"enabled": true,
"name": "Just a Name",
"metricName": "justaname",
"metricExpression": "(100)*(builtin:service.errors.server.successCount:splitBy())/(builtin:service.requestCount.server:splitBy())",
"evaluationType": "AGGREGATE",
"filter": "type(\"SERVICE\")",
"evaluationWindow": "-1w",
"targetSuccess": 99.98,
"targetWarning": 99.99,
"errorBudgetBurnRate": {
"burnRateVisualizationEnabled": true,
"fastBurnThreshold": 10.0
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"key": "graphql.operation.name",
"masking": "NOT_MASKED"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
configs:
- id: 1f4b1f5c-11d2-38c8-9324-7d139c6e6452
config:
name: 1f4b1f5c-11d2-38c8-9324-7d139c6e6452
template: 1f4b1f5c-11d2-38c8-9324-7d139c6e6452.json
skip: false
type:
settings:
schema: builtin:span-attribute
schemaVersion: 0.0.32
scope: environment
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
configs:
- id: d955d9b7-9630-3be5-aca5-3715779a7282
config:
name: d955d9b7-9630-3be5-aca5-3715779a7282
template: d955d9b7-9630-3be5-aca5-3715779a7282.json
skip: false
type:
settings:
schema: builtin:monitoring.slo
schemaVersion: 6.0.12
scope: environment
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"enabled": true,
"name": "NEW Name",
"metricName": "justaname",
"metricExpression": "(100)*(builtin:service.errors.server.successCount:splitBy())/(builtin:service.requestCount.server:splitBy())",
"evaluationType": "AGGREGATE",
"filter": "type(\"SERVICE\")",
"evaluationWindow": "-1w",
"targetSuccess": 99.98,
"targetWarning": 99.99,
"errorBudgetBurnRate": {
"burnRateVisualizationEnabled": true,
"fastBurnThreshold": 10.0
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"key": "graphql.operation.name",
"masking": "NOT_MASKED"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
configs:
- id: 1f4b1f5c-11d2-38c8-9324-7d139c6e6452
config:
name: 1f4b1f5c-11d2-38c8-9324-7d139c6e6452
template: 1f4b1f5c-11d2-38c8-9324-7d139c6e6452.json
skip: false
type:
settings:
schema: builtin:span-attribute
schemaVersion: 0.0.32
scope: environment
56 changes: 0 additions & 56 deletions pkg/client/dtclient/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (
"fmt"
"github.com/dynatrace/dynatrace-configuration-as-code/v2/internal/cache"
"github.com/dynatrace/dynatrace-configuration-as-code/v2/internal/concurrency"
"github.com/dynatrace/dynatrace-configuration-as-code/v2/internal/filter"
"github.com/dynatrace/dynatrace-configuration-as-code/v2/internal/idutils"
"github.com/dynatrace/dynatrace-configuration-as-code/v2/internal/log"
"github.com/dynatrace/dynatrace-configuration-as-code/v2/internal/log/field"
Expand Down Expand Up @@ -560,61 +559,6 @@ func (d *DynatraceClient) getSettingById(ctx context.Context, objectId string) (
return &result, nil
}

func (d *DynatraceClient) ListSettings(ctx context.Context, schemaId string, opts ListSettingsOptions) (res []DownloadSettingsObject, err error) {
d.limiter.ExecuteBlocking(func() {
res, err = d.listSettings(ctx, schemaId, opts)
})
return
}

func (d *DynatraceClient) listSettings(ctx context.Context, schemaId string, opts ListSettingsOptions) ([]DownloadSettingsObject, error) {

if settings, cached := d.settingsCache.Get(schemaId); cached {
log.Debug("Using cached settings for schema %s", schemaId)
return filter.FilterSlice(settings, opts.Filter), nil
}

log.Debug("Downloading all settings for schema %s", schemaId)

listSettingsFields := defaultListSettingsFields
if opts.DiscardValue {
listSettingsFields = reducedListSettingsFields
}
params := url.Values{
"schemaIds": []string{schemaId},
"pageSize": []string{defaultPageSize},
"fields": []string{listSettingsFields},
}

result := make([]DownloadSettingsObject, 0)

addToResult := func(body []byte) (int, error) {
var parsed struct {
Items []DownloadSettingsObject `json:"items"`
}
if err := json.Unmarshal(body, &parsed); err != nil {
return 0, fmt.Errorf("failed to unmarshal response: %w", err)
}

result = append(result, parsed.Items...)
return len(parsed.Items), nil
}

u, err := buildUrl(d.environmentURL, d.settingsObjectAPIPath, params)
if err != nil {
return nil, fmt.Errorf("failed to list settings: %w", err)
}

_, err = rest.ListPaginated(ctx, d.platformClient, d.retrySettings, u, schemaId, addToResult)
if err != nil {
return nil, err
}

d.settingsCache.Set(schemaId, result)

return filter.FilterSlice(result, opts.Filter), nil
}

type EntitiesTypeListResponse struct {
Types []EntitiesType `json:"types"`
}
Expand Down
106 changes: 0 additions & 106 deletions pkg/client/dtclient/client_settings_test.go

This file was deleted.

Loading

0 comments on commit d17d26b

Please sign in to comment.