Store Dynatrace settings
- How-to guide
- 10-min read
This guide shows you how to use the Settings SDK to read and manage Dynatrace settings objects.
The Settings SDK gives access to all Dynatrace settings: App Settings (schemas defined by app developers) and built-in settings (schemas defined by Dynatrace). Read more about the general concept in Settings service.
Install the SDK
Install the required SDK via the terminal:
npm i @dynatrace-sdk/client-settings
For the full API reference, see the Settings API.
Understand scopes and schema IDs
Every settings object has a scope that identifies its target. Pass "environment" for environment-wide settings, or a Smartscape node ID for entity-specific settings.
Every object belongs to a schema, identified by a schema ID. Schema IDs follow different conventions depending on the settings type:
- Built-in Dynatrace settings use the
builtin:prefix, for example"builtin:maintenance-windows". - App Settings schemas use the format
"app:<app-identifier>:<schema-identifier>", for example"app:my.app:my-example".
Discover available schemas
To list the schemas you can work with, use settingsSchemasClient.listSchemaDefinitions. By default, only schemaId, displayName, and latestSchemaVersion are returned. Use addFields to include additional metadata.
import { settingsSchemasClient } from '@dynatrace-sdk/client-settings';
const schemas = await settingsSchemasClient.listSchemaDefinitions({
addFields: 'multiObject,ordered,ownerBasedAccessControl',
});
To get the full definition of a specific schema, including its properties and constraints:
import { settingsSchemasClient } from '@dynatrace-sdk/client-settings';
const schema = await settingsSchemasClient.getSchemaDefinition({
schemaId: 'builtin:maintenance-windows',
});
This operation requires the scope settings:schemas:read. Read more about scopes in this guide.
Support interactive settings editing
The settingsInteractiveEditingSupportClient provides helper operations intended for building interactive settings editors — for example, a UI that guides users through creating or editing a settings object.
Generate a default value for a schema
To get the default value object for a schema (useful for pre-populating a new settings form), use generateSchemaDefaultValue:
import { settingsInteractiveEditingSupportClient } from '@dynatrace-sdk/client-settings';
const defaults = await settingsInteractiveEditingSupportClient.generateSchemaDefaultValue({
schemaId: 'builtin:maintenance-windows',
scope: 'environment',
});
Generate a summary for a settings value
To generate a human-readable summary string for a given settings value without storing it, use summarizeSettingsValue. This is useful for previewing how a value will appear in list views:
import { settingsInteractiveEditingSupportClient } from '@dynatrace-sdk/client-settings';
const summary = await settingsInteractiveEditingSupportClient.summarizeSettingsValue({
schemaId: 'builtin:maintenance-windows',
body: {
value: {
name: 'Weekend maintenance',
},
},
});
Validate a settings value
To validate a settings value or property against a custom validator defined in the schema without saving it, use validateSettingsContainer (for a full object) or validateSettingsProperty (for a single property):
import { settingsInteractiveEditingSupportClient } from '@dynatrace-sdk/client-settings';
const result = await settingsInteractiveEditingSupportClient.validateSettingsContainer({
schemaId: 'builtin:maintenance-windows',
validatorId: 'schedule-validator',
scope: 'environment',
body: {
value: {
trigger: {
type: 'time',
recurring: { time: '02:00:00' },
},
duration: 60,
},
},
});
import { settingsInteractiveEditingSupportClient } from '@dynatrace-sdk/client-settings';
const result = await settingsInteractiveEditingSupportClient.validateSettingsProperty({
schemaId: 'builtin:maintenance-windows',
validatorId: 'filter-validator',
body: {
value: 'entity.type == "HOST"',
},
});
This operation requires the scope settings:schemas:read. Read more about scopes in this guide.
Get effective settings values
Effective values represent the resolved configuration for a given schema and scope. Use this when you want to read configuration in your app rather than manage it.
The operation evaluates the full hierarchy of persisted objects and always returns a result for any schema and scope combination, even if the schema is not specifically relevant to the given entity. Resolution works as follows:
- If a settings object is persisted at the requested scope, its value is returned.
- If no object is persisted at the requested scope, the value is inherited from the parent scope (for example, the kubernetes cluster, and then the environment level).
- If no object is persisted anywhere along the hierarchy, the default value as defined in the schema is returned.
import { settingsObjectsClient } from '@dynatrace-sdk/client-settings';
const result = await settingsObjectsClient.listEffectiveSettingsValues({
schemaId: 'builtin:maintenance-windows',
scope: 'environment',
addFields: 'summary,value',
});
The result depends on the multiObject property of the schema:
false: a single object is returned, containing either the persisted value or the schema default.true: the merged list of persisted objects along the hierarchy is returned, or an empty list if nothing is persisted and no default is defined.
This operation requires the scope settings:objects:read. Read more about scopes in this guide.
Get stored settings objects
To fetch only explicitly stored objects (without schema default fallback), use settingsObjectsClient.listSettingsObjects. Use this together with update or delete operations to manage settings.
By default, only objectId and version are returned. Specify additional fields in addFields, and use filter and sort to narrow the results.
You can filter and sort by:
modificationInfo.createdBymodificationInfo.createdTimemodificationInfo.lastModifiedBymodificationInfo.lastModifiedTimevaluewith properties and sub-properties separated by a dot (for example,value.enabled = true)externalIdowner.typeowner.id
Note that only fields included via addFields can be used for filtering and sorting.
import { settingsObjectsClient } from '@dynatrace-sdk/client-settings';
const objects = await settingsObjectsClient.listSettingsObjects({
schemaId: 'builtin:maintenance-windows',
scope: 'environment',
addFields: 'value,summary,modificationInfo',
filter: 'value.enabled = true',
sort: '-modificationInfo.lastModifiedTime',
});
To fetch a single object by its ID:
import { settingsObjectsClient } from '@dynatrace-sdk/client-settings';
const object = await settingsObjectsClient.getSettingsObject({
objectId: '<objectId>',
addFields: 'value,summary',
});
Properties of type secret are always returned as masked values.
This operation requires the scope settings:objects:read. Read more about scopes in this guide.
Create a settings object
To create a new settings object, use settingsObjectsClient.upsertSettingsObject. You must provide the schemaId, scope, and value.
import { settingsObjectsClient } from '@dynatrace-sdk/client-settings';
const response = await settingsObjectsClient.upsertSettingsObject({
body: {
schemaId: 'builtin:maintenance-windows',
scope: 'environment',
value: {
name: 'Weekend maintenance',
enabled: true,
schedule: {
trigger: {
type: 'time',
recurring: { time: '02:00:00' },
},
duration: 60,
},
filter: 'entity.type == "HOST"',
autoDelete: false,
},
},
});
The response contains the objectId and version of the newly created object. You need the objectId to update or delete the object, and the version for optimistic locking.
This operation requires the scope settings:objects:write. Read more about scopes in this guide.
Update a settings object
To update an existing object, use settingsObjectsClient.updateSettingsObject. You must provide the current version from a previous GET response to prevent overwriting concurrent changes.
To update a property of type secret, pass the new value in plain text. To keep the current value, send the current masked secret (retrieved via a GET request).
Some schemas don't allow passing of the masked secret. In that case you must send the unmasked secret with every update of the object, regardless of whether the secret itself changed. Check the schema definition to determine whether this applies.
import { settingsObjectsClient } from '@dynatrace-sdk/client-settings';
const objects = await settingsObjectsClient.listSettingsObjects({
schemaId: 'builtin:maintenance-windows',
scope: 'environment',
});
await settingsObjectsClient.updateSettingsObject({
objectId: objects.items[0].objectId,
optimisticLockingVersion: objects.items[0].version,
body: {
value: {
name: 'Weekend maintenance',
enabled: false,
schedule: {
trigger: {
type: 'time',
recurring: { time: '02:00:00' },
},
duration: 120,
},
filter: 'entity.type == "HOST"',
autoDelete: false,
},
},
});
Remember that version changes on every modification. Always use the most recently retrieved version for updates.
This operation requires the scope settings:objects:write. Read more about scopes in this guide.
Delete a settings object
To delete an object, use settingsObjectsClient.deleteSettingsObject with its objectId and current version:
import { settingsObjectsClient } from '@dynatrace-sdk/client-settings';
const objects = await settingsObjectsClient.listSettingsObjects({
schemaId: 'builtin:maintenance-windows',
scope: 'environment',
});
await settingsObjectsClient.deleteSettingsObject({
objectId: objects.items[0].objectId,
optimisticLockingVersion: objects.items[0].version,
});
This operation requires the scope settings:objects:write. Read more about scopes in this guide.
Reorder settings objects
For schemas that are both multiObject and ordered, you can reorder the objects using settingsObjectsClient.reorderSettingsObjects. The request requires the current version from the list response. If any objects change concurrently, the reorder is rejected to prevent overwriting changes.
import { settingsObjectsClient } from '@dynatrace-sdk/client-settings';
const objects = await settingsObjectsClient.listSettingsObjects({
schemaId: 'builtin:maintenance-windows',
scope: 'environment',
});
await settingsObjectsClient.reorderSettingsObjects({
optimisticLockingVersion: objects.optimisticLockingVersion,
body: {
schemaId: 'builtin:maintenance-windows',
scope: 'environment',
sections: [
{
firstObjectId: objects.items[0].objectId,
lastObjectId: objects.items[objects.items.length - 1].objectId,
order: objects.items.map((item) => ({ objectId: item.objectId })).reverse(),
},
],
},
});
This operation requires the scope settings:objects:write. Read more about scopes in this guide.
Get effective settings permissions
To check whether the calling user has specific permissions for given schemas and scopes, use settingsPermissionsClient.resolveEffectivePermissions:
import { settingsPermissionsClient } from '@dynatrace-sdk/client-settings';
const permissions = await settingsPermissionsClient.resolveEffectivePermissions({
body: {
permissions: [
{
permission: 'settings:objects:read',
context: { schemaId: 'builtin:maintenance-windows', scope: 'environment' },
},
{
permission: 'settings:objects:write',
context: { schemaId: 'builtin:maintenance-windows', scope: 'environment' },
},
],
},
});
The function returns an array with the resolution result for each requested permission:
[
{
"permission": "settings:objects:read",
"granted": "true",
"context": { "schemaId": "builtin:maintenance-windows", "scope": "environment" }
},
{
"permission": "settings:objects:write",
"granted": "false",
"context": { "schemaId": "builtin:maintenance-windows", "scope": "environment" }
}
]
This operation requires the scope settings:schemas:read. Read more about scopes in this guide.
You can also query user permissions.
Owner-based access control
If a schema has ownerBasedAccessControl enabled, the user who first creates an object is its owner. Only the owner can read or write that object by default.
The following sections mention accessors. An accessor can be a specific user, a group, or the all-users type, which applies to all users.
Transfer ownership
An owner has read and write access to their object. A settings object can have only one owner.
To transfer ownership, use settingsPermissionsClient.transferSettingsObjectOwnership. After the transfer, the previous owner loses access unless they were granted explicit permissions beforehand.
import { settingsPermissionsClient } from '@dynatrace-sdk/client-settings';
await settingsPermissionsClient.transferSettingsObjectOwnership({
objectId: '<objectId>',
body: {
newOwner: {
type: 'user',
id: '550e8400-e29b-41d4-a716-446655440000',
},
},
});
This operation requires the scope settings:objects:write. Read more about scopes in this guide.
Add permissions for an accessor
To grant permissions to a user or group for a settings object, use settingsPermissionsClient.addSettingsObjectAccessorPermissions. Only users with read and write access on the object can add permissions for new accessors.
import { settingsPermissionsClient } from '@dynatrace-sdk/client-settings';
await settingsPermissionsClient.addSettingsObjectAccessorPermissions({
objectId: '<objectId>',
body: {
accessor: {
type: 'group',
id: 'f81d4fae-7dec-11d0-a765-00a0c91e6bf6',
},
permissions: ['r', 'w'],
},
});
This operation requires the scope settings:objects:write. Read more about scopes in this guide.
Get permissions for all accessors
Use settingsPermissionsClient.getSettingsObjectPermissions to get all permissions for a specific settings object:
import { settingsPermissionsClient } from '@dynatrace-sdk/client-settings';
const permissions = await settingsPermissionsClient.getSettingsObjectPermissions({
objectId: '<objectId>',
});
This operation requires the scope settings:objects:read. Read more about scopes in this guide.
Update permissions for an accessor
To update permissions for an existing accessor, use settingsPermissionsClient.updateSettingsObjectAccessorPermissions for user and group accessors, or settingsPermissionsClient.updateSettingsObjectAllUsersPermissions for the all-users type:
import { settingsPermissionsClient } from '@dynatrace-sdk/client-settings';
await settingsPermissionsClient.updateSettingsObjectAccessorPermissions({
objectId: '<objectId>',
accessorType: 'group',
accessorId: 'f81d4fae-7dec-11d0-a765-00a0c91e6bf6',
body: {
permissions: ['r'],
},
});
This operation requires the scope settings:objects:write. Read more about scopes in this guide.
Remove permissions for an accessor
To remove all permissions for an accessor, use settingsPermissionsClient.deleteSettingsObjectAccessorPermissions (for user and group) or settingsPermissionsClient.deleteSettingsObjectAllUsersPermissions (for all-users):
import { settingsPermissionsClient } from '@dynatrace-sdk/client-settings';
await settingsPermissionsClient.deleteSettingsObjectAllUsersPermissions({
objectId: '<objectId>',
});
This operation requires the scope settings:objects:write. Read more about scopes in this guide.
Administrator access
To bypass access checks for administrator tasks, pass adminAccess: true to any read or write operation. This requires the settings:objects:admin scope.
import { settingsObjectsClient } from '@dynatrace-sdk/client-settings';
const objects = await settingsObjectsClient.listSettingsObjects({
schemaId: 'builtin:maintenance-windows',
scope: 'environment',
adminAccess: true,
});
This operation requires the following scopes:
settings:objects:writesettings:objects:admin
Review settings history
To retrieve the revision history of settings objects, use settingsHistoryClient.listSettingsHistory. You must provide schemaIds and scope, and optionally filter by modification time or user.
By default, only revisions from the last two weeks are returned. Use the filter parameter to specify a wider or narrower time range.
import { settingsHistoryClient } from '@dynatrace-sdk/client-settings';
const history = await settingsHistoryClient.listSettingsHistory({
schemaIds: 'builtin:maintenance-windows',
scope: 'environment',
addFields: 'revision,modificationInfo,jsonBefore,jsonAfter',
sort: '-modificationInfo.lastModifiedTime',
});
Supported addFields for history: revision, jsonPatch, jsonBefore, jsonAfter, objectId, type, schemaVersion, modificationInfo, schemaId, schemaDisplayName, summary, appId, source, ownerBefore, ownerAfter.
You can filter history by:
revisionobjectIdschemaVersionmodificationInfo.lastModifiedTimemodificationInfo.lastModifiedBy
This operation requires the scope settings:objects:read. Read more about scopes in this guide.