Payload Syntax¶
Customizing General¶
The customizing payload can be defined in either of the following standards:
The Terraform language uses the following types for its values:
string: a sequence of Unicode characters representing some text, like"hello".number: a numeric value. The number type can represent both whole numbers like 15 and fractional values like6.283185.bool: a boolean value, eithertrueorfalse(lowercase!). bool values can be used in conditional logic.list (or tuple): a sequence of values, like["user1", "user2"].map (or dictionary): a group of values identified by named labels, like{name = "nwheeler", security_clearance = 50}.
Most of the customizing settings may have an optional field called enabled that allows to dynamically turn on / off customization settings based on a boolean value that may be read from a Terraform variable (or could just be false or true). In case you are using additional external payload (see above) you need to provide false or true directly. If enabled is not specified then enabled = True is assumed (this is the default).
The YAML language uses the following types for its values:
string: a sequence of Unicode characters representing some text, likehello.number: a numeric value. The number type can represent both whole numbers like 15 and fractional values like6.283185.bool: a boolean value, eithertrueorfalse.list: a sequence of values, like["user1", "user2"]ordictionary: a group of values identified by named labels, like{name: nwheeler, security_clearance: 50}.
Sample usage:
Most of the customizing settings may have an optional field called enabled that allows to dynamically turn on / off customization settings based on a boolean value. If enabled is not specified then enabled = True is assumed (this is the default).
payloadOptions¶
This section defines options that are used to manage the payload. This is only required when using the Customizer as a Service (API).
payloadSections¶
This section defines the payload sections that are used and defines the order in which they are processed.
Only the sections listed here are processed. If a payload has no payloadSections, nothing is processed.
Each list element is a dictionary with these fields:
name(str, mandatory) - the name of the payload section, for examplegroupsortransportPackagesenabled(bool) - set totrueto process the section. The data of a section is only loaded if its entry inpayloadSectionshasenabled = true, so always set this value explicitly.restart(bool, optional, default =false) - restart the Content Management frontend and backend services after this section has been processed
The entry for the users section supports these additional fields:
additional_instances(int, optional, default =0) - create additional copies of all users in theuserssection. The copies get a two-digit number as suffix of the login name and the last name.user_customization(bool, optional, default =true) - process the user profile photos (and related user customizations) after the users have been createdjato_enabled(bool, optional, default =true) - use thejatoSmart View theme for the user profiles (otherwise thecftheme is used)
payloadSections = [
{ name = "adminSettings", enabled = true },
{ name = "groups", enabled = true },
{ name = "users", enabled = true, additional_instances = 0 },
{ name = "webReports", enabled = true },
{ name = "transportPackages", enabled = true, restart = true },
{ name = "permissions", enabled = true },
]
Post sections¶
Some sections exist a second time with the suffix Post: groupsPost, usersPost, adminSettingsPost,
transportPackagesPost, itemsPost, permissionsPost, webReportsPost, webHooksPost, sapRFCsPost,
and browserAutomationsPost. A Post section uses exactly the same syntax as the section without the suffix. It
is a separate payload key with its own data, so the same kind of configuration can be applied at a second point in
time, typically after the transport packages have been deployed. Like every other section, a Post section is only
processed if it is listed in payloadSections; its position in that list defines when it is processed.
OTDS Customizing Syntax¶
The payload syntax for OTDS customizing uses the following lists (the list elements are maps):
resources¶
resources allows to create new resources in OTDS.
Each list element includes a switch enabled to turn them on or off. This switch can be controlled by a Terraform variable.
In addition, each resource definition has a name, an optional description, and an optional display_name. It is also possible to activate the new resource via the activate = true. With resource_id and secret pre-defined values can be provided for the resource ID and the secret. The secret should be 24 characters long and end with ==. If a secret and a resource ID are provided, then the resource is automatically activated. Otherwise you can enforce activation with activate = true. With additional_payload a dictionary of key value pairs can be provided:
resources = [
{
enabled = true
name = "Aviator Search"
description = "Resource for Aviator Search"
display_name = "Resource for Aviator Search"
allow_impersonation = true
activate = true # if a secret is provided the resource will automatically be activated
resource_id = "a331e5cb-68ef-4cb7-a8a0-037ba6b35522"
secret = "0123456789012345678901==" # needs to end with ==
additional_payload = {
"pcCreatePermissionAllowed": true,
"pcModifyPermissionAllowed": true,
"pcDeletePermissionAllowed": false,
}
}
]
resources:
- enabled: true
name: "Aviator Search"
description: "Resource for Aviator Search"
display_name: "Resource for Aviator Search"
allow_impersonation: true
activate: true # if a secret is provided the resource will automatically be activated
resource_id: "a331e5cb-68ef-4cb7-a8a0-037ba6b35522"
secret: "0123456789012345678901==" # needs to end with ==
additional_payload:
pcCreatePermissionAllowed: true
pcModifyPermissionAllowed: true
pcDeletePermissionAllowed: false
synchronized partition¶
synchronized partition allows to create a new synchronized partition in otds
Each list element includes a switch enabled to turn them on or off. This switch can be controlled by a Terraform variable.
In addition, the name of each synchronized partition is taken from profileName in spec and the optional description from description in spec. It is also possible to directly put the new synchronized partition into an existing access_role. Also licenses this synchronized partition should be assigned to can be specified:
In case of importing Active Directory users and groups ignore licenses.
synchronizedPartitions = [
{
access_role = "Access to cs"
licenses = ["X2", "ADDON_AVIATOR", "ADDON_MEDIA"]
spec = {
"ipConnectionParameter": [
{
"hostName": host,
"portNumber": port,
"encryptionMethod": 0
}
],
"ipAuthentication": {
"bindDN": user,
"authenticationMethod": 1,
"qualityOfProtection": 0,
"bindPassword": "password need to be sent from secrets and set it to my_customizer.otds_settings.bindPassword "
"servicePrincipalName": "ldap/undefined",
"kerberosCredentialType": 0
},
"objectClassNameMapping": [
{
"objectType": 0,
"destObject": "oTPerson",
"sourceFilter": "(|(objectClass=organizationalPerson)(objectClass=posixAccount))",
"attributeMapping": [
{
"sourceAttr": [
"cn"
],
"destAttr": "cn",
"mappingFormat": "%s"
},
{
"sourceAttr": [
""
],
"destAttr": "oTDepartment",
"mappingFormat": "[Tenant Administrators Group]"
},
{
"sourceAttr": [
""
],
"destAttr": "oTType",
"mappingFormat": "TenantAdminUser"
}
],
"syncPairMapping": [
{
"sourceLocation": "ou=People,ou=WEM1672,dc=opentext,dc=com",
"recurse": 1
}
],
"mustMappedAttributes": [
"cn"
]
},
{
"objectType": 1,
"destObject": "oTGroup",
"sourceFilter": "(objectClass=groupOfUniqueNames)",
"attributeMapping": [
{
"sourceAttr": [
"cn"
],
"destAttr": "cn",
"mappingFormat": "%s"
},
{
"sourceAttr": [
""
],
"destAttr": "oTType",
"mappingFormat": "TenantAdminUser"
}
],
"syncPairMapping": [
{
"sourceLocation": "ou=Groups,ou=WEM1672,dc=opentext,dc=com",
"recurse": 1
}
],
"mustMappedAttributes": [
"cn"
]
}
],
"basicAttributes": [
{
"attrId": "externalIDType",
"attrValues": [
"0"
]
},
{
"attrId": "externalIDAttribute",
"attrValues": [
"mail"
]
},
{
"attrId": "importUsersFromMatchedGroups",
"attrValues": [
"0"
]
},
{
"attrId": "oTSearchFilterUsersAttributes",
"attrValues": [
""
]
},
{
"attrId": "oTSearchFilterGroupsAttributes",
"attrValues": [
""
]
},
{
"attrId": "fullSyncSchedule",
"attrValues": [
"0 0 0 1,2,3,4,5,6,7"
]
}
],
"basicInfo": {
"enableUUIDTracking": true,
"externalIDAttribute": "mail",
"groupLoginAttr": "cn",
"memberAttr": [
"uniqueMember",
"member"
],
"monitorChanges": true,
"monitoringFullSyncStartTime": "0000",
"monitoringPingTime": 5,
"monitoringType": "2",
"objectUUIDAttribute": "nsUniqueId",
"pagedSearchPageSize": 200,
"schemaType": 6,
"searchType": "1",
"supportDirSyncControl": false,
"supportedSASLMechanisms": "(2): EXTERNAL; DIGEST-MD5",
"supportPagedSearchControl": false,
"supportPersistentSearchControl": true,
"supportUnlimitedSearch": false,
"supportUSNQuery": false,
"supportVLVControl": true,
"userLoginAttr": "uid",
"vlvsearchPageSize": "200",
"vlvsortingAttribute": "entryDN"
},
"baseDN": "dc=opentext,dc=com",
"profileName": "csActiveDirectory",
"description": "Partition contains Active Directory users and groups",
"ipSchemaType": 6,
"authProvider": 1
}
}
]
synchronizedPartitions:
- access_role: "Access to cs"
spec:
ipConnectionParameter:
- hostName: hostname
portNumber: port
encryptionMethod: 0
ipAuthentication:
bindDN: user
authenticationMethod: 1
qualityOfProtection: 0
bindPassword: ## password need to be sent from secrets and set it to my_customizer.otds_settings.bindPassword
servicePrincipalName: ldap/undefined
kerberosCredentialType: 0
objectClassNameMapping:
- objectType: 0
destObject: oTPerson
sourceFilter: (|(objectClass=organizationalPerson)(objectClass=posixAccount))
## add all the required attributes as mentioned in below format
attributeMapping:
- sourceAttr: ["cn"]
destAttr: cn
mappingFormat: '%s'
- sourceAttr: [""]
destAttr: oTDepartment
mappingFormat: "[Tenant Administrators Group]"
- sourceAttr: [""]
destAttr: oTType
mappingFormat: TenantAdminUser
syncPairMapping:
- sourceLocation: "ou=People,ou=WEM1672,dc=opentext,dc=com"
recurse: 1
mustMappedAttributes: ["cn"]
- objectType: 1
destObject: oTGroup
sourceFilter: (objectClass=groupOfUniqueNames)
## add all the required attributes as mentioned in below format
attributeMapping:
- sourceAttr: ["cn"]
destAttr: cn
mappingFormat: '%s'
- sourceAttr: [""]
destAttr: oTType
mappingFormat: TenantAdminUser
syncPairMapping:
- sourceLocation: "ou=Groups,ou=WEM1672,dc=opentext,dc=com"
recurse: 1
mustMappedAttributes: ["cn"]
basicAttributes:
- attrId: externalIDType
attrValues: ["0"]
- attrId: externalIDAttribute
attrValues: ["mail"]
- attrId: importUsersFromMatchedGroups
attrValues: ["0"]
- attrId: oTSearchFilterUsersAttributes
attrValues: [""]
- attrId: oTSearchFilterGroupsAttributes
attrValues: [""]
- attrId: fullSyncSchedule
attrValues: ["0 0 0 1,2,3,4,5,6,7"]
basicInfo:
enableUUIDTracking: true
externalIDAttribute: mail
groupLoginAttr: cn
memberAttr:
- uniqueMember
- member
monitorChanges: true
monitoringFullSyncStartTime: '0000'
monitoringPingTime: 5
monitoringType: '2'
objectUUIDAttribute: nsUniqueId
pagedSearchPageSize: 200
schemaType: 6
searchType: '1'
supportDirSyncControl: false
supportedSASLMechanisms: '(2): EXTERNAL; DIGEST-MD5'
supportPagedSearchControl: false
supportPersistentSearchControl: true
supportUnlimitedSearch: false
supportUSNQuery: false
supportVLVControl: true
userLoginAttr: uid
vlvsearchPageSize: '200'
vlvsortingAttribute: entryDN
baseDN: dc=opentext,dc=com
profileName: csActiveDirectory
description: "Partition contains Active Directory users and groups"
ipSchemaType: 6
authProvider: 1
partitions¶
partitions allows to create new partitions in OTDS.
Each list element includes a switch enabled to turn them on or off. This switch can be controlled by a Terraform variable.
In addition, each partition has a name, an optional description. It is also possible to directly put the new partition into an existing access_role. Also licenses this partition should be assigned to can be specified:
licenses¶
licenses allows to assign a license to a resource.
Each list element includes a switch enabled to turn them on or off. This switch can be controlled by a Terraform variable.
oauthClients¶
oauthClients allows to create a list of new OAuth client in OTDS.
Each list element includes a switch enabled to turn them on or off. This switch can be controlled by a Terraform variable.
name defines the name of the OTDS OAuth client and description should describe what the OAuth client is used for. Each OAuth client has the typical elements such as confidential (default is true), OTDS partition (default is Global), redirect_urls, permission_scopes, default_scopes, and allow_impersonation. If there's a predefined secret it can be provided by secret. The user_type of the user in Content Server can be changed, default is "", which is a standard user. It can be changed to "ServiceUser".
oauthClients = [
{
enabled = var.enable_salesforce
name = "salesforce"
description = "OAuth client for Salesforce"
confidential = true
partition = "Global"
redirect_urls = ["https://salesforce.com/services/authcallback/OTDS"]
permission_scopes = ["full"]
default_scopes = ["full"]
allow_impersonation = true
secret = var.salesforce_oauth_secret
user_type = "ServiceUser"
}
]
oauthClients:
- allow_impersonation: true
confidential: true
default_scopes:
- full
description: OAuth client for Salesforce
enabled: ${var.enable_salesforce}
name: salesforce
partition: Global
permission_scopes:
- full
redirect_urls:
- https://salesforce.com/services/authcallback/OTDS
secret: ${var.salesforce_oauth_secret}
user_type: "ServiceUser"
authHandlers¶
authHandlers is a list of additional OTDS authentication handlers.
Each list element can include a switch called enabled to turn them on or off (the default is true). This switch can be controlled by a Terraform variable.
In addition, each handler has a name, type and an optional description. Further values can be specified that depends on the type of the handler. Supported types are SAML, OAUTH, or SAP. The values can also use terraform variables.
Optional keys for all handler types:
scope(str) - name of the user partition that limits the scope of the handlerpriority(int) - priority of the handler compared to other handlersactive_by_default(bool, default =false) - redirect to the identity provider immediately instead of showing the OTDS login page
Additional optional keys for SAML handlers:
auth_principal_attributes(list) - list of authentication principal attributesnameid_format(str) - NameID format of the identity provider that contains the user identifier
authHandlers = [
{
enabled = true
name = "..."
description = "..."
type = "..." # either SAML, OAUTH, or SAP
provider_name = "..." # required for SAML and OAUTH
saml_url = "..." # required for SAML
otds_sp_endpoint = "https://${local.otds_dns_name}/otdsws/login" # required for SAML
certificate_file = "..." # required only for SAP
certificate_password = "..." # required only for SAP
client_id = "..." # required only for OAUTH
client_secret = "..." # required only for OAUTH
active_by_default = false # replace standard OTDS login page
authorization_endpoint = "..." # required only for OAUTH
token_endpoint = "..." # required only for OAUTH
scope_string = "id"
},
]
authHandlers:
- active_by_default: false
authorization_endpoint: '...'
certificate_file: '...'
certificate_password: '...'
client_id: '...'
client_secret: '...'
description: '...'
enabled: true
name: '...'
otds_sp_endpoint: https://${local.otds_dns_name}/otdsws/login
provider_name: '...'
saml_url: '...'
scope_string: '...'
token_endpoint: '...'
type: '...'
trustedSites¶
trustedSites allows you to define trusted sites for OTDS.
Each list element can include a switch called enabled to turn them on or off (the default is true). This switch can be controlled by a Terraform variable.
The actual URL for the trusted site is given by the field url. Regular expressions are allowed to define patterns for the URL.
trustedSites = [
{
enabled = var.enable_successfactors
url = "https://[^/]+\\.successfactors\\.eu/.*"
},
{
enabled = var.enable_successfactors
url = "https://[^/]+\\.successfactors\\.com/.*"
},
{
enabled = var.enable_salesforce
url = "https://[^/]+\\.salesforce\\.com/.*"
},
{
enabled = var.enable_salesforce
url = "https://[^/]+\\.force\\.com/.*"
},
{
enabled = var.enable_o365
url = "https://[^/]+\\.microsoft\\.com/.*"
},
{
enabled = var.enable_o365
url = "https://[^/]+\\.sharepoint\\.com/.*"
},
{
enabled = var.enable_o365
url = "https://[^/]+\\.office\\.com/.*"
},
{
enabled = var.enable_appworks
url = "https://${local.otawp_dns_name}" # AppWorks endpoint
},
]
trustedSites:
- enabled: ${var.enable_successfactors}
url: https://[^/]+\\.successfactors\\.eu/.*
- enabled: ${var.enable_successfactors}
url: https://[^/]+\\.successfactors\\.com/.*
- enabled: ${var.enable_salesforce}
url: https://[^/]+\\.salesforce\\.com/.*
- enabled: ${var.enable_salesforce}
url: https://[^/]+\\.force\\.com/.*
- enabled: ${var.enable_o365}
url: https://[^/]+\\.microsoft\\.com/.*
- enabled: ${var.enable_o365}
url: https://[^/]+\\.sharepoint\\.com/.*
- enabled: ${var.enable_o365}
url: https://[^/]+\\.office\\.com/.*
- enabled: ${var.enable_appworks}
url: https://${local.otawp_dns_name}
systemAttributes¶
systemAttributes allows you to set system attributes in OTDS.
Each list element can include a switch called enabled to turn them on or off (the default is true). This switch can be controlled by a Terraform variable.
In addition, each system attribute has a name, value and an optional description.
additionalGroupMemberships¶
additionalGroupMemberships allows adding pre-existing users or groups to existing OTDS groups. Each list element can include an enabled switch to turn the item on or off (default is true).
Each element consists of a parent_group value combined with either a group_name or user_name value.
additionalAccessRoleMemberships¶
additionalAccessRoleMemberships allows adding pre-existing users, groups, or partitions to existing OTDS Access Roles.
Each list element can include an enabled switch to turn the item on or off (default is true).
Each element consists of an access_role value combined with either a group_name, user_name, or partition_name value.
additionalAccessRoleMemberships = [
{
access_role = "Access to cs"
group_name = "otdsadmins@otds.admin"
},
{
# Add the Content Server Members partition to the AppworksGateway access role
enabled = var.enable_appworks_gateway
access_role = "Access to gatewayresource"
partition_name = "Content Server Members"
}
]
additionalApplicationRoleAssignments¶
additionalApplicationRoleAssignments allows adding pre-existing users or groups to existing OTDS application roles.
Each list element can include an enabled switch to turn the item on or off (default is true).
Each element should include:
role_name(required): eitherroleorrole@partition.user_name(optional): user to assign (mutually exclusive withgroup_name).group_name(optional): group to assign (mutually exclusive withuser_name).
applicationRoles¶
applicationRoles creates application roles in OTDS.
Each list element is a dictionary with these fields:
enabled(bool, optional, default =true) - switch to turn the payload element on or offname(str, mandatory) - name of the application roledescription(str, optional) - description of the application rolepartition(str, optional, default =OAuthClients) - name of the OTDS partition the role is created invalues(list, optional) - additional values passed to OTDS when the role is createdcustom_attributes(list, optional) - custom attributes passed to OTDS when the role is created
Content Management Customizing Syntax¶
The payload syntax for Content Management configurations uses these lists (list elements are maps / dictionaries):
groups¶
groups is a list of Content Management user groups that are automatically created during the deployment.
Each list element can include a switch called enabled to turn them on or off (the default is true). This switch can be controlled by a Terraform variable.
In addition, each group has a name and (optionally) a list of parent groups. enable_o365, enable_salesforce, and enable_core_share are used to control whether or not a Microsoft 365, Salesforce or Core Share group should be created matching the OpenText Content Management group. The example below shows two groups. The Finance group is a child group of the Innovate group. The Finance group is also created in Microsoft 365 if the variable var.enable_o365 evaluates to true.
users¶
users is a list of OpenText Content Management users that are automatically created during deployment.
Each list element can include a switch called enabled to turn them on or off (the default is true). This switch can be controlled by a Terraform variable.
In addition, users should have name, password, firstname, lastname, email, title, and company. The password of these users can also be randomly generated and can be printed by terraform output -json (all users have the same password). Each user needs to have a base group that must be in the groups section of the payload. Optionally a user can have a list of additional groups. A user can also have a list of favorites. Favorites can either be the logical name of a workspace instance used in the payload (see workspace below) or it can be a nickname of an OpenText Content Management item. Users can also have a security clearance level and multiple supplemental markings. Both are optional. security_clearance is used to define the security clearance level of the user. This needs to match one of the existing security clearance levels that have been defined in the securityClearances section in the payload. supplemental_markings defines a list of supplemental markings the user should get. These need to match markings defined in the supplementalMarkings section in the payload. The field privileges defines the standard privileges of a user. If it is omitted users get the default privileges ["Login", "Public Access"]. The optional field for service users is type with values User or ServiceUser (default is User).
The customizing module is also able to automatically configure Microsoft 365 users for each OpenText Content Management user. To make this work, the Terraform variable for Office 365 / Microsoft 365 need to be configured. In particular var.enable_o365 needs to be true. In the user settings enable_o365 has to be set to true as well (or you use the variable var.enable_o365 if the payload is in the customization.tf file). m365_skus defines a list of Microsoft 365 SKUs that should be assigned to the user. These are the technical SKU IDs that are documented by Microsoft: Licensing Service Plans. Inside the customizing.tf file you also find a convenient map called m365_skus that map the SKU ID to readable names (such as "Microsoft 365 E3" or "Microsoft 365 E5"). The enable_sap, enable_successfactors, enable_salesforce, enable_core_share allow to automatically create + configure the users in connected SAP S/4HANA, SuccessFactors, Salesforce, and Core Share applications respectively.
users = [
{
name = "adminton"
password = local.password
firstname = "Adam"
lastname = "Minton"
email = "adminton@innovate.com"
title = "Administrator"
base_group = "Administration"
groups = ["IT"]
favorites = ["workspace-a", "nickname-a"]
security_clearance = 50
supplemental_markings = ["EUZONE"]
privileges = ["Login", "Public Access", "Content Manager", "Modify Users", "Modify Groups", "User Admin Rights", "Grant Discovery", "System Admin Rights"]
enable_o365 = var.enable_o365
m365_skus = [var.m365_skus["Microsoft 365 E3"]]
enable_sap = var.enable_o365
enable_successfactors = var.enable_o365
enable_salesforce = var.enable_o365
enable_core_share = var.enable_o365
extra_attributes = [
{
name = "oTExtraAttr0"
value = "adminton${var.salesforce_username_suffix}"
}
]
},
{
name = "nwheeler"
password = local.password
firstname = "Nick"
lastname = "Wheeler"
email = "nwheeler@innovate.com"
title = "Sales Director"
base_group = "Sales"
groups = ["Manager", "Office365"]
favorites = ["workspace-b", "nickname-b"]
security_clearance = 95
supplemental_markings = ["EU-GDPR-PD", "EUZONE"]
privileges = ["Login", "Public Access"]
enable_o365 = var.enable_o365
m365_skus = [var.m365_skus["Microsoft 365 E5"]]
enable_sap = var.enable_o365
enable_successfactors = var.enable_o365
enable_salesforce = var.enable_o365
enable_core_share = var.enable_o365
}
]
users:
- base_group: Administration
email: adminton@innovate.com
enable_o365: ${var.enable_o365}
extra_attributes:
- name: oTExtraAttr0
value: adminton${var.salesforce_username_suffix}
favorites:
- workspace-a
- nickname-a
firstname: Adam
groups:
- IT
lastname: Minton
m365_skus:
- ${var.m365_skus["Microsoft 365 E3"]}
name: adminton
password: ${local.password}
privileges:
- Login
- Public Access
- Content Manager
- Modify Users
- Modify Groups
- User Admin Rights
- Grant Discovery
- System Admin Rights
security_clearance: 50
supplemental_markings:
- EUZONE
title: Administrator
- base_group: Sales
email: nwheeler@innovate.com
enable_o365: ${var.enable_o365}
enable_sap: ${var.enable_sap}
enable_successfactors: ${var.enable_successfactors}
enable_salesforce: ${var.enable_salesforce}
enable_core_share: ${var.enable_core_share}
favorites:
- workspace-b
- nickname-b
firstname: Nick
groups:
- Manager
- Office365
lastname: Wheeler
name: nwheeler
password: ${local.password}
privileges:
- Login
- Public Access
security_clearance: 95
supplemental_markings:
- EU-GDPR-PD
- EUZONE
title: Sales Director
items¶
items and itemsPost are lists of OpenText Content Management items such as folders, shortcuts or URLs that should be created automatically but are not included in transports. All items are created in the Enterprise Workspace of OpenText Content Management or any subfolder.
Each list element can include a switch called enabled to turn them on or off (the default is true). This switch can be controlled by a Terraform variable.
In addition, each item needs to have name and type values. The parent ID of the item can either be specified by a nick name (parent_nickname) or by the path in the Enterprise Workspace (parent_path). The value parent_path is a list of folder names starting from the root level in the Enterprise Workspaces. parent_path = ["Administration", "WebReports"] creates the item in the WebReports folder which is itself in the Administration top-level folder. The list items is processed at the beginning of the automation (before transports are applied) and itemsPost is applied at the end of the automation (after transports have been applied).
items = [
{
enabled = true
parent_nickname = "" # empty string = not set
parent_path = ["Administration", "WebReports"]
name = "Case Management"
description = "Case Management with eFiles and eCases"
type = var.otcs_item_types["Folder"]
url = "" # "" = not set
original_nickname = 0 # 0 = not set
original_path = [] # [] = not set
},
]
itemsPost = [
{
parent_nickname = "" # empty string = not set
parent_path = [
"Administration", "Websites"
]
name = "OpenText Homepage"
description = "The OpenText web site"
type = var.otcs_item_types["URL"]
url = "https://www.opentext.com"
original_nickname = 0 # 0 = not set
original_path = [] # [] = not set
}
]
items:
- description: Case Management with eFiles and eCases
enabled: true
name: Case Management
original_nickname: 0
original_path: []
parent_nickname: ''
parent_path:
- Administration
- WebReports
type: ${var.otcs_item_types["Folder"]}
url: ''
itemsPost:
- description: The OpenText web site
enabled: true
name: OpenText Homepage
original_nickname: 0
original_path: []
parent_nickname: ''
parent_path:
- Administration
- Websites
type: ${var.otcs_item_types["URL"]}
url: https://www.opentext.com
permissions¶
permissions and permissionsPost are both lists of Extended ECM items, each with a specific permission set that should be applied to the item.
Each list element can include a switch called enabled to turn them on or off (the default is true). This switch can be controlled by a Terraform variable.
In addition, the item can be specified via a path (list of folder names in Enterprise workspace in top-down order), via a nickname, or via a volume. Permission values are listed as list strings in [...] for owner_permissions, owner_group_permissions, or public_permissions. They can be a combination of the following values: see, see_contents, modify, edit_attributes, add_items, reserve, add_major_version, delete_versions, delete, and edit_permissions. The apply_to specifies if the permissions should only be applied to the item itself (value 0) or only to sub-items (value 1) or the item and its sub-items (value 2). The list specified by permissions is applied before the transport packages are applied and permissionsPost is applied after the transport packages have been processed.
permissions = [
{
enabled = true
path = ["...", "..."]
volume = "..." # identified by volume type ID
nickname = "..." # an item with this nick name needs to exist
owner_permissions = []
owner_group_permissions = []
public_permissions = ["see", "see_contents"]
groups = [
{
name = "..."
permissions = []
}
]
users = [
{
name = "..."
permissions = []
}
]
apply_to = 2
}
]
renamings¶
renamings is a list of OpenText Content Management items (e.g. volume names) that are automatically renamed during deployment.
Each list element can include a switch called enabled to turn them on or off (the default is true). This switch can be controlled by a Terraform variable.
In addition, you have to either provide the nodeid (only a few node IDs are really known upfront such as 2000 for the Enterprise Workspace) or a volume (type ID) with an optional path in that volume. Another alternative is to use a nickname to specify the node to be renamed. In case of volumes there's a list of known volume types defined at the beginning of the customizing.tf file with the variable otcs_volumes. You can also specify a description that will be used to update the description of the node / item.
renamings = [
{
enabled = true
nodeid = 2000
name = "Innovate"
description = "Innovate's Enterprise Workspace"
},
{
enabled = true
volume = var.otcs_volumes["Content Server Document Templates"]
name = "Content Server Document Templates"
description = "OpenText Content Management Workspace and Document Templates"
}
]
adminSettings¶
adminSettings and adminSettingsPost are lists of admin settings that are applied before the transport packages (adminSettings) or directly after the transport packages (adminSettingsPost) in the customizing process.
Each list element can include a switch called enabled to turn them on or off (the default is true). This switch can be controlled by a Terraform variable (or could just be false or true).
In addition, each setting is defined by a description, the filename of an XML file that includes the actual OpenText Content Management admin settings that are applied automatically (using XML import / LLConfig). These files need to be stored inside the setting/payload sub-folder inside the terraform folder.
adminSettings = [
{
description = "Apply minimum settings for Government Desktop (Inbox) that are required before users and groups are created."
filename = "GovernmentSettings-Inbox.xml", # this needs to happen before users and groups are created
},
{
enabled = var.enable_o365
description = "These settings are removed by a side-effect during MS Teams automation. We need to re-enable them."
filename = "O365Settings.xml",
}
]
adminSettingsPost = [
{
description = "Apply Document Template settings that are dependent on Classification elements."
filename = "DocumentTemplatesSettings.xml"
},
]
adminSettings:
- description: Apply minimum settings for Government Desktop (Inbox) that are required
before users and groups are created.
filename: GovernmentSettings-Inbox.xml
- description: These settings are removed by a side-effect during MS Teams automation.
We need to re-enable them.
enabled: ${var.enable_o365}
filename: O365Settings.xml
adminSettingsPost:
- description: Apply Document Template settings that are dependent on Classification
elements.
filename: DocumentTemplatesSettings.xml
docgenSettings¶
docgenSettings allows you to set settings in OpenText Content Management Document Generation (OTPD - PowerDocs).
Each list element can include a switch called enabled to turn them on or off (the default is true). This switch can be controlled by a Terraform variable.
In addition, each document generation setting has a name, value and an optional tenant.
docgenSettings = [
{
enabled = true
name = "LocalOtdsUrl"
value = "http://otds/otdsws"
},
{
description = "Fix settings for local Kubernetes deployments"
enabled = true
name = "LocalApplicationServerUrlForContentManager"
value = "http://localhost:8080/c4ApplicationServer"
tenant = "Successfactors"
}
]
externalSystems¶
externalSystems is a list of connections to external business applications such as SAP S/4HANA, Salesforce, or SuccessFactors. Some of the payload elements are common, some are specific for the type of the external system.
Each list element can include a switch called enabled to turn them on or off (the default is true). This switch can be controlled by a Terraform variable (or could just be false or true).
In addition, the field external_system_type needs to have one of these values: SAP, SAP-OAuth, Salesforce, SuccessFactors, Guidewire, AppWorks Platform or Business Scenario Sample. All other fields are dependent on the selection of the external_system_type value.
SAP-OAuth is an SAP system that OpenText Content Management connects to with OAuth instead of a technical user: it uses oauth_client_id, oauth_client_secret, token_endpoint and optionally request_type (BASIC or HTTPBODY) - username and password are not needed. as_url_v4 (optional, all SAP types) is the URL of the S/4HANA OData V4 API server.
For SAP, base_url also enables the OData REST APIs of pyxecm's SAP object. The optional saml_* fields enable principal propagation - pyxecm calls SAP as the individual user instead of the technical user (see SAP Authentication / SSO):
| Field | Meaning |
|---|---|
saml_idp_private_key_file |
PEM private key of pyxecm's SAML 2.0 identity provider - a file in the customizer pod, e.g. mounted from a Kubernetes secret |
saml_idp_certificate_file |
PEM certificate of that key - the SAP administrator trusts it in transaction SAML2 |
saml_issuer |
Entity ID of pyxecm's identity provider as registered in SAML2, e.g. pyxecm-idp |
saml_audience |
Provider name of the SAP system's local SAML 2.0 provider (SAML2), e.g. S4HCLNT100 |
Never put the key itself into the payload - only the file name.
externalSystems = [
{
enabled = var.enable_sap
external_system_type = "SAP"
external_system_name = "S4H"
external_system_number = var.sap_external_system_number
description = "SAP S/4HANA on-premise"
as_url = "https://s4.example.com:44300/sap/bc/srt/xip/otx/ecmlinkservice/100/ecmlinkspiservice/basicauthbinding"
base_url = "https://s4.example.com:44300"
client = var.sap_external_system_client
username = "demo"
password = local.password
certificate_file = "/certificates/S4H.pse"
certificate_password = "topsecret"
destination = var.sap_external_system_destination
archive_logical_name = var.sap_archive_logical_name
archive_certificate_file = "/certificates/${var.sap_archive_certificate_file}"
# Optional - principal propagation (pyxecm as SAML 2.0 identity provider):
saml_idp_private_key_file = "/secrets/saml-idp.key"
saml_idp_certificate_file = "/secrets/saml-idp.crt"
saml_issuer = "pyxecm-idp"
saml_audience = "S4HCLNT100"
},
{
enabled = var.enable_salesforce
external_system_type = "Salesforce"
external_system_name = "SFDC-HTTP"
description = "Salesforce"
as_url = "https://idea02dev-dev-ed.my.salesforce.com/services/Soap/c/48.0/"
base_url = "https://idea02dev-dev-ed.my.salesforce.com"
username = "idea02a2dev@opentext.com"
password = local.password
oauth_client_id = "..."
oauth_client_secret = "..."
authorization_endpoint = "https://salesforce.com/services/oauth2/authorize"
token_endpoint = "https://salesforce.com/services/oauth2/token"
},
{
enabled = var.enable_successfactors
external_system_type = "SuccessFactors"
external_system_name = "SuccessFactors"
description = "SAP SuccessFactors"
as_url = "https://apisalesdemo8.successfactors.com/odata/v2"
base_url = "https://pmsalesdemo8.successfactors.com"
username = "sfadmin@SFPART035780"
password = local.password
saml_url = "https://salesdemo.successfactors.eu/idp/samlmetadata?company=SFSALES004711"
otds_sp_endpoint = "https://otds.xecm-cloud.com/otdsws"
oauth_client_id = "..."
oauth_client_secret = "..."
}
]
externalSystems:
- archive_logical_name: ${var.sap_archive_logical_name}
archive_certificate_file: "/certificates/${var.sap_archive_certificate_file}"
as_url: https://s4.example.com:44300/sap/bc/srt/xip/otx/ecmlinkservice/100/ecmlinkspiservice/basicauthbinding
base_url: https://s4.example.com:44300
certificate_file: /certificates/S4H.pse
certificate_password: topsecret
client: ${var.sap_external_system_client}
description: SAP S/4HANA on-premise
destination: ${var.sap_external_system_destination}
enabled: ${var.enable_sap}
external_system_name: S4H
external_system_type: SAP
password: ${local.password}
saml_audience: S4HCLNT100
saml_idp_certificate_file: /secrets/saml-idp.crt
saml_idp_private_key_file: /secrets/saml-idp.key
saml_issuer: pyxecm-idp
username: demo
- as_url: https://idea02dev-dev-ed.my.salesforce.com/services/Soap/c/48.0/
authorization_endpoint: https://salesforce.com/services/oauth2/authorize
base_url: https://idea02dev-dev-ed.my.salesforce.com
description: Salesforce
enabled: ${var.enable_salesforce}
external_system_name: SFDC-HTTP
external_system_type: Salesforce
oauth_client_id: '...'
oauth_client_secret: '...'
password: ${local.password}
token_endpoint: https://salesforce.com/services/oauth2/token
username: idea02a2dev@opentext.com
- as_url: https://apisalesdemo8.successfactors.com/odata/v2
base_url: https://pmsalesdemo8.successfactors.com
description: SAP SuccessFactors
enabled: ${var.enable_successfactors}
external_system_name: SuccessFactors
external_system_type: SuccessFactors
oauth_client_id: '...'
oauth_client_secret: '...'
otds_sp_endpoint: https://otds.xecm-cloud.com/otdsws
password: ${local.password}
saml_url: https://salesdemo.successfactors.eu/idp/samlmetadata?company=SFSALES004711
username: sfadmin@SFPART035780
transportPackages¶
transportPackages is a list of transport packages that should be applied automatically. These packages need to be accessible via the provided URLs.
Each list element can include a switch called enabled to turn them on or off (the default is true). This switch can be controlled by a Terraform variable (or could just be false or true).
In addition, the name must be the exact file name of the ZIP package. A value for description is optional.
transportPackages = [
{
enabled = true
url = "https://terrarium.blob.core.windows.net/transports/Terrarium-010-Categories.zip"
name = "Terrarium 010 Categories.zip"
description = "Terrarium Category definitions"
},
{
url = "https://terrarium.blob.core.windows.net/transports/Terrarium-020-Classifications.zip"
name = "Terrarium 20 Classifications.zip"
description = "Terrarium Classification definitions"
},
{
enabled = var.enable_sap
url = "${var.transporturl}/Terrarium-110-Business-Object-Types-SAP.zip"
name = "Terrarium 110 Business Object Types (SAP).zip"
description = "Terrarium Business Object types for SAP"
extractions = [
{
enabled = true
xpath = "/livelink/llnode[@objtype='889']"
}
]
},
{
enabled = var.enable_o365
url = "${var.transporturl}/Terrarium-115-Scheduled-Processing-Microsoft.zip"
name = "Terrarium 115 Scheduled Processing (Microsoft).zip"
description = "Terrarium Scheduled Processing Jobs for Microsoft Office 365"
replacements = [
{
placeholder = "M365x62444544.onmicrosoft.com"
value = var.o365_domain
},
{
placeholder = "M365x61936377.onmicrosoft.com"
value = var.o365_domain
}
]
}
]
transportPackages:
- description: Terrarium Category definitions
name: Terrarium 010 Categories.zip
url: https://terrarium.blob.core.windows.net/transports/Terrarium-010-Categories.zip
- description: Terrarium Classification definitions
name: Terrarium 20 Classifications.zip
url: https://terrarium.blob.core.windows.net/transports/Terrarium-020-Classifications.zip
contentTransportPackages¶
contentTransportPackages is a list of content transport packages that should be automatically applied. Content Transport Package typically are used to import documents into workspaces that are created before. These packages need to be accessible via the provided URLs.
Each list element can include a switch called enabled to turn them on or off (the default is true). This switch can be controlled by a Terraform variable (or could just be false or true).
The name must be the exact file name of the ZIP package. Description is optional. Other than the transportPackages these transports are deployed after users and workspace instances have been processed. This allows to transport content into workspaces instances or use users inside these transport packages (e.g. owners, user attributes, etc.)
contentTransportPackages = [
{
url = "${var.transporturl}/Terrarium-300-Government-Content.zip"
name = "Terrarium 300 Government Content.zip"
description = "Terrarium demo documents for Government scenario"
},
{
url = "${var.transporturl}/Terrarium-310-Enterprise-Asset-Management-Content.zip"
name = "Terrarium 310 Enterprise Asset Management Content.zip"
description = "Terrarium demo documents for Enterprise Asset Management scenario"
}
]
contentTransportPackages:
- description: Terrarium demo documents for Government scenario
name: Terrarium 300 Government Content.zip
url: ${var.transporturl}/Terrarium-300-Government-Content.zip
- description: Terrarium demo documents for Enterprise Asset Management scenario
name: Terrarium 310 Enterprise Asset Management Content.zip
url: ${var.transporturl}/Terrarium-310-Enterprise-Asset-Management-Content.zip
workspaceTemplates¶
workspaceTemplates is a list of workspace templates that should be modified before used by the workspace processing.
This payload allows to change the role memberships (adding new users or groups) and to add additional categories to workspace templates.
Each element is a dict with these keys:
enabled(bool, optional, default = True)type_name(str, mandatory)template_name(str, mandatory)members(list, optional)role(str, mandatory)users(list, optional, default = [])groups(list, optional, default = [])categories(list, optional)nickname(str, optional) - the nickname of the categorypath(list, optional) - the path to the category object in the category volumeinheritance(bool, optional) - should category inheritance be turned on on the workspace template node?apply_to_sub_items(bool, optional) - should the category be inherited to existing sub-items?
workspaces¶
workspaces is a list of business workspaces instances that should be automatically created. Category, Roles, and Business Relationships can be provided.
Each list element can include a switch called enabled to turn them on or off (the default is true). This switch can be controlled by a Terraform variable (or could just be false or true).
In addition, the id needs to be a unique value in the payload. It does not need to be something related to any of the actual OpenText Content Management workspace data. It is only used to establish relationship between different workspaces in the payload (using the list of related workspaces in relationships). Important: If the workspace type definition uses a pattern to generate the workspace name then the name in the payload should match the pattern in the workspace type definition. Otherwise incremental deployments of the payload may not find the existing workspaces and may try to recreate them resulting in an error. The nickname is the OpenText Content Management nickname that allows to refer to this item without knowing its technical ID.
The relationships are given as a list of related workspaces. The elements of the list can be:
- string or integer with logical workspace ID
- string with nickname of the related workspace
- list of dictionaries with
typeandnameof the related workspace - list of strings with the top-down path in the Enterprise volume
Business Object information can be provided with a business_objects list. Each list item defines the external system (see above), the business object type, and business object ID. This list is optional.
Roles and membership information is provided with the members list. Each list item defines membership for a single workspace role which is defined with role. Members can be defined by two lists: users and groups. In the first example below the role Sales Representative is populated with user nwheeler and with the groups Sales and Management.
Classification information is optional and can be provided separately for Records Management classifications and normal/regular classifications. Both types of classifications need to be provided as paths inside the respective classifications trees (top down). There can be only one Records Management classification but multiple regular classifications. That's why the element classification_pathes is a list of paths.
Category information is provided in a list of blocks. Each block includes the category name, set name (optional, can be empty if the attribute is not in a set), attribute name, and the attribute value. Multi-value attributes are a comma-separated list of items in square brackets. The example below shows a customer workspace and a contract workspace that are related to each other (the customer workspace has an attribute Sales Organization that has multiple values: 1000 and 2000). The contract workspace has a multi-line attribute set. For multi-line attribute sets the payload needs an additional row value that specifies the row number in the multi-line set (starting with 1 for the first row).
A third workspace in the example below is for Material - it has an additional field called template_name which is optional. It can be used if there are multiple templates for one workspace type. If it is not specified and the workspace type has multiple workspace templates the first template is automatically selected.
workspaces = [
{
id = "50031"
name = "Global Trade AG (50031)"
nickname = "ws_customer_global_trade"
description = "Strategic customer in Germany"
type_name = "Customer"
template_name = "Customer"
business_objects = [
{
external_system = var.sap_external_system_name
bo_type = "KNA1"
bo_id = "0000050031"
}
]
members = [
{
role = "Sales Representative"
users = ["nwheeler"]
groups = ["Sales", "Management"]
}
]
classification_pathes = []
rm_classification_path = [
"RM Classifications",
"Case Management",
"Building Authorities",
"01.Buildings",
"01.Building applications",
"02.Alteration and repair",
]
categories = [
{
name = "Customer"
set = ""
attribute = "Customer Number"
value = "50031"
},
{
name = "Customer"
set = ""
attribute = "Sales organisation"
value = ["1000", "2000"]
},
{
name = "Customer"
set = "Rating"
attribute = "Institute"
value = "Dun & Bradstreet"
}
]
relationships = [
"0040000019"
]
},
{
id = "0040000019"
name = "0040000019 - Global Trade AG"
description = ""
type_name = "Sales Contract"
members = [
{
role = "Contract Manager"
users = ["dfoxhoven"]
}
]
categories = [
{
name = "Contract"
set = "Contract Data"
attribute = "Function"
value = "Sales"
},
{
name = "Contract"
set = "Contract Data"
attribute = "Contract Number"
value = "0040000019"
},
{
name = "Contract"
set = "Contract Line Items"
row = 1
attribute = "Material Number"
value = "P-100"
}
]
},
{
id = "R-9010"
name = "R-9010 - Notebook WebCam Model '16"
description = ""
type_name = "Material"
template_name = "Material (Operating Supplies)"
members = [
{
role = "Master Data Management"
users = ["kmurray"]
}
]
categories = [
{
name = "Material"
set = ""
attribute = "Material Number"
value = "R-9010"
},
{
name = "Material"
set = ""
attribute = "Material Description"
value = "Notebook WebCam Model '16"
}
]
}
]
workspaces:
- business_objects:
- bo_id: '0000050031'
bo_type: KNA1
external_system: ${var.sap_external_system_name}
categories:
- attribute: Customer Number
name: Customer
set: ''
value: '50031'
- attribute: Sales organisation
name: Customer
set: ''
value:
- '1000'
- '2000'
- attribute: Institute
name: Customer
set: Rating
value: Dun & Bradstreet
classification_pathes: []
description: Strategic customer in Germany
id: '50031'
members:
- groups:
- Sales
- Management
role: Sales Representative
users:
- nwheeler
name: Global Trade AG (50031)
relationships:
- 0040000019
rm_classification_path:
- RM Classifications
- Case Management
- Building Authorities
- 01.Buildings
- 01.Building applications
- 02.Alteration and repair
template_name: Customer
type_name: Customer
- categories:
- attribute: Function
name: Contract
set: Contract Data
value: Sales
- attribute: Contract Number
name: Contract
set: Contract Data
value: 0040000019
- attribute: Material Number
name: Contract
row: 1
set: Contract Line Items
value: P-100
description: ''
id: 0040000019
members:
- role: Contract Manager
users:
- dfoxhoven
name: 0040000019 - Global Trade AG
type_name: Sales Contract
- categories:
- attribute: Material Number
name: Material
set: ''
value: R-9010
- attribute: Material Description
name: Material
set: ''
value: Notebook WebCam Model '16
description: ''
id: R-9010
members:
- role: Master Data Management
users:
- kmurray
name: R-9010 - Notebook WebCam Model '16
template_name: Material (Operating Supplies)
type_name: Material
webReports¶
webReports and webReportsPost are two lists of OpenText Content Management web reports that should be automatically executed during deployment. Having two lists gives you the option to run some webReports after the business configuration and some others after demo content has been produced. These Web Reports have typically been deployed to OpenText Content Management system with the transport warehouse before. Each list item specifies one Web Report.
Each list element can include a switch called enabled to turn them on or off (the default is true). This switch can be controlled by a Terraform variable (or could just be false or true).
In addition, the nickname is mandatory and defines the nickname of the Web Report to be executed. So you need to give each webReport you want to run a nickname before putting it in a transport package. The element description is optional. The parameters set defines parameter name and parameter value pairs. The corresponding Web Report in OpenText Content Management must have exactly these parameters defined.
webReports = [
{
nickname = "web_report_unset_xgov_doc_view"
description = "Web Report to disable the Brava document view side bar"
parameters = {
"user_name" = "swang"
}
},
{
nickname = "web_report_set_cust_sf"
description = "Web Report to auto-configure OpenText Content Management for SuccessFactors Module Specific Settings"
}
]
webReportsPost = [
{
nickname = "web_report_set_cust_sf"
description = "Web Report to auto-configure OpenText Content Management for SuccessFactors Module Specific Settings"
}
]
webReports:
- description: Web Report to disable the Brava document view side bar
nickname: web_report_unset_xgov_doc_view
parameters:
user_name: swang
- description: Web Report to auto-configure OpenText Content Management for SuccessFactors Module
Specific Settings
nickname: web_report_set_cust_sf
webReportsPost:
- description: Web Report to auto-configure OpenText Content Management for SuccessFactors Module
Specific Settings
nickname: web_report_set_cust_sf
csApplications¶
csApplications is a list of Content Server Applications that should automatically be deployed.
Each list element can include a switch called enabled to turn them on or off (the default is true). This switch can be controlled by a Terraform variable (or could just be false or true).
In addition, each element has a name for the application and optionally a description.
assignments¶
assignments is a list of assignments. Assignments are typically used for Extended ECM for Government.
Each list element can include a switch called enabled to turn them on or off (the default is true). This switch can be controlled by a Terraform variable (or could just be false or true).
Each assignment assigns either a workspace or an OpenText Content Management item with a nickname to a defined list of users or groups. Assignments have a subject (title) and an optional instruction for the target users or groups.
documentGenerators¶
documentGenerators defines a list of document generators that is based on the document template capabilities of OpenText Content Management. Each element is a dictionary with these fields:
enabledswitch to turn payload element on or off (the default istrue)workspace_typeis the name of the workspace type. It is a mandatory field.template_pathis a mandatory list for folder names (top-down). It is a mandatory information.classification_pathis a mandatory list of classification elements (top-down)category_nameis the name of the category (optional)attributesis a list of dictionaries containing the attribute information. The dictionary has keysnameandvalue.workspace_folder_path(list, optional, default = []) - default puts the document in the workspace rootexec_as_useris optional and defines the name (login ID) of the user. If not provided the document is generated with admin credentials.
documentGenerators = [
{
exec_as_user = "pwilliams"
workspace_type = "Purchase Contract"
workspace_folder_path = ["01 - Contract"]
template_path = ["Procurement", "Document Templates", "Purchasing Contract.docx"]
classification_path = ["Types", "Document Types", "Procurement", "Purchase Contract"]
category_name = "Contract Document"
attributes = [
{
name = "Status"
value = "Approved"
},
{
name = "Legal Approval"
value = "dfoxhoven"
},
{
name = "Legal Approval Date"
value = "2023-05-11"
},
{
name = "Management Approval"
value = "pwilliams"
},
{
name = "Management Approval Date"
value = "2023-05-12"
},
{
name = "Official Document"
value = true
},
{
name = "Language"
value = "EN"
},
{
name = "File Type"
value = "MS Word"
},
]
},
...
]
workflows¶
workflows is a list of workflow definitions. For each instance of the given workspace type, the Customizer starts the
workflow and then processes its steps in order.
The data is read from the payload key workflows, but the processing step is called workflowInitiations.
Therefore payloadSections currently needs both entries: workflows (to load the data; the
Customizer logs an "Illegal payload section name" error for it, which can be ignored) and workflowInitiations
at the position where the workflows should be started (after the workspaces have been created):
payloadSections:
- name: workflows
enabled: true
# ... other sections ...
- name: workflowInitiations
enabled: true
Each element is a dictionary with these fields:
enabled(bool, optional, default =true) - switch to turn the payload element on or offworkflow_nickname(str, mandatory) - the nickname of the workflow mapworkspace_type(str, mandatory) - the name of the workspace type. For each instance of this workspace type a workflow is started.workspace_folder_path(list, optional) - path of the subfolder in the workspace that contains the documents the workflow is started with. All documents in this folder are attached to the workflow. If the path is not given, or does not exist in a workspace, the documents in the workspace root folder are used.steps(list, mandatory) - the workflow steps, processed in the given order. The first step must have the actionInitiate. If a step fails, the remaining steps for this workspace are skipped.
Each step is a dictionary with these fields:
action(str, mandatory) -Initiatestarts the workflow. Any other value is passed as the action name to the current task of the started workflow (Content Server REST API, for exampleformUpdate). The user inexec_as_usermust have the task in their inbox.exec_as_user(str, mandatory) - login name of the user that executes the step. The user must be defined in the users section of the payload.attributes(list, optional) - workflow attribute values to set in this step. Each list element is a dictionary with the keysname(the attribute name in the workflow definition),valueand an optionaltype. Iftypeisuser, thenvalueis the login name of a user and is converted to the user ID.title(str, optional) - title of the workflow. Only used by theInitiateaction.comment(str, optional) - comment of the workflow initiator. Only used by theInitiateaction.due_in_days(int, optional) - number of days until the workflow is due (the due date is the current date plus this number of days). Only used by theInitiateaction.
workflows = [
{
enabled = true
workflow_nickname = "wf_contract_approval_workflow"
workspace_type = "Purchase Contract"
workspace_folder_path = ["01 - Contract"]
steps = [
{
action = "Initiate"
exec_as_user = "pwilliams"
title = "Contract Approval Workflow for Purchase Contracts"
comment = "Workflow initiated by Terrarium automation"
due_in_days = 4
attributes = [
{
name = "Approver"
value = "dfoxhoven"
type = "user"
}
]
}
]
}
]
workflows:
- enabled: true
workflow_nickname: wf_contract_approval_workflow
workspace_type: Purchase Contract
workspace_folder_path:
- 01 - Contract
steps:
- action: Initiate
exec_as_user: pwilliams
title: Contract Approval Workflow for Purchase Contracts
comment: Workflow initiated by Terrarium automation
due_in_days: 4
attributes:
- name: Approver
value: dfoxhoven
type: user
ontologies¶
ontologies is a list of ontologies (domains). An ontology describes relationships between workspace types (entities) and optionally synonyms and key aspects of these types. The workspace types must already exist, so list this section in payloadSections after the transport packages that create them.
The same workspace type can be part of multiple ontologies. In this case the synonyms, key aspects and predicates of all ontologies are merged, and relationships that already exist on the workspace type are not duplicated.
Each list element is a dictionary with these fields:
enabled(bool, optional, default =true) - switch to turn the payload element on or offname(str, mandatory) - name of the ontology / domainlocale(str, optional, default = system default metadata language of Content Management, oren) - language code used for synonyms, key aspects and predicates that are given as plain stringsentities(list of dict, mandatory) - the workspace types that are part of the ontology. If empty, the ontology is skipped. Each element has these keys:name(str, mandatory) - name of an existing workspace typedescription(str, optional, default = empty) - free text description of the workspace type. Domains, synonyms and key aspects are appended to it for older versions of Content Management that have no native support for these values.synonyms(list of str or dict, optional) - synonyms of the workspace type. Either a list of strings (assigned tolocale) or a dictionary with language codes as keys and lists of strings as values.key_aspects(list of str or dict, optional) - key aspects of the workspace type. Same format assynonyms.
relationships(list of dict, mandatory) - the relationships between workspace types. If empty, the ontology is skipped. Each element has these keys:source_type(str, mandatory) - name of the workspace type the relationship starts from. It should be listed inentities, as relationships are only processed for the entities of the ontology.target_type(str, mandatory) - name of the existing workspace type the relationship points todirection(str, optional, default =child) - type of the relationship. Eitherchildorparent.predicates(list of str or dict, optional) - phrases that describe the relationship (e.g. "has"). Each element is either a string (assigned tolocale) or a dictionary with a language code as key and the phrase as value.
ontologies = [
{
enabled = true
name = "Contract Management"
locale = "en"
entities = [
{
name = "Contract"
description = "A legal agreement between two or more parties"
synonyms = ["Agreement"]
key_aspects = ["Contract Value", "Expiration Date"]
},
{
name = "Vendor"
synonyms = {
en = ["Supplier"]
de = ["Lieferant"]
}
}
]
relationships = [
{
source_type = "Contract"
target_type = "Vendor"
direction = "child"
predicates = ["is signed with", { de = "wird abgeschlossen mit" }]
}
]
}
]
ontologies:
- enabled: true
name: Contract Management
locale: en
entities:
- name: Contract
description: A legal agreement between two or more parties
synonyms:
- Agreement
key_aspects:
- Contract Value
- Expiration Date
- name: Vendor
synonyms:
en:
- Supplier
de:
- Lieferant
relationships:
- source_type: Contract
target_type: Vendor
direction: child
predicates:
- is signed with
- de: wird abgeschlossen mit
workspacePermissions¶
workspacePermissions is a list of permission settings that are applied to all workspace instances of a given workspace type (or to a folder inside each of these workspaces). List it in payloadSections after the sections that create the workspaces.
Each list element is a dictionary with these fields:
enabled(bool, optional, default =true) - switch to turn the payload element on or offworkspace_type(str, mandatory) - name of the workspace type. The type must exist, otherwise the element is skipped with an error.workspace_folder(str, optional) - name of a folder inside each workspace. If specified, the permissions are applied to this folder instead of the workspace itself. Workspaces that do not contain such a folder are skipped. If omitted, the permissions are applied to the workspace itself.regex(bool, optional, default =false) - iftrue,workspace_folderis interpreted as a regular expression to find the folder in the workspace. Otherwise it is an exact folder name.owner_permissions(list of str, optional) - permissions of the item owner. Only applied if the key is present.owner_group_permissions(list of str, optional) - permissions of the owner group. Only applied if the key is present.public_permissions(list of str, optional) - permissions of the public access. Only applied if the key is present.groups(list of dict, optional) - permissions for specific groups. Each element has these keys:name(str, mandatory) - name of the grouppermissions(list of str, mandatory) - the permissions of the group
users(list of dict, optional) - permissions for specific users. Each element has these keys:name(str, mandatory) - login name of the userpermissions(list of str, mandatory) - the permissions of the user
apply_to(int, optional, default =2) - specifies if the permissions are applied only to the item itself (value0), only to its sub-items (value1), to the item and its sub-items (value2), or to the item and its immediate sub-items (value3)
Permission values are the same as for permissions: see, see_contents, modify, edit_attributes, add_items, reserve, add_major_version, delete_versions, delete, and edit_permissions.
workspacePermissions = [
{
enabled = true
workspace_type = "Contract"
workspace_folder = "Documents"
regex = false
owner_permissions = ["see", "see_contents", "modify"]
owner_group_permissions = ["see", "see_contents"]
public_permissions = []
groups = [
{
name = "Contract Managers"
permissions = ["see", "see_contents", "modify", "add_items"]
}
]
users = [
{
name = "jdoe"
permissions = ["see", "see_contents"]
}
]
apply_to = 2
}
]
workspacePermissions:
- enabled: true
workspace_type: Contract
workspace_folder: Documents
regex: false
owner_permissions:
- see
- see_contents
- modify
owner_group_permissions:
- see
- see_contents
public_permissions: []
groups:
- name: Contract Managers
permissions:
- see
- see_contents
- modify
- add_items
users:
- name: jdoe
permissions:
- see
- see_contents
apply_to: 2
categoryAssignments¶
categoryAssignments is a list of category assignments. Each element assigns a category to an existing item (identified by nickname or path) and sets attribute values of that category. If the category is already assigned to the item, only the attribute values are updated.
Each list element is a dictionary with these fields:
enabled(bool, optional, default =true) - switch to turn the payload element on or offitem(str or list of str, mandatory) - the item the category is assigned to. A string is interpreted as a nickname of the item. A list is interpreted as a path (list of folder names in top-down order) in the Enterprise Workspace or in the volume given byvolume.volume(int, optional, default = Enterprise Workspace volume) - volume type ID used to resolveitemif it is a pathcategory_item(str or list of str, mandatory) - the category to assign. A string is interpreted as a nickname of the category. A list is interpreted as a path in the Categories Volume.categories(list of dict, mandatory) - the attribute values to set. All elements must refer to the same category, and the category name must match the name of the category given bycategory_item. Each element has these keys:name(str, mandatory) - name of the categoryattribute(str, mandatory) - name of the attributevalue(str, mandatory) - value of the attribute. For user attributes this is the login name of the user.set(str, optional) - name of the set if the attribute is part of a setrow(int, optional) - row number for attributes in multi-row sets (mandatory for such attributes)
apply_to_sub_items(bool, optional, default =false) - iftrue, the category is also assigned to all sub-items of the iteminheritance(bool, optional, default =false) - iftrue, the category is inherited by items added to the item later (category inheritance)
categoryAssignments = [
{
enabled = true
item = ["Contracts", "Templates"]
volume = 141
category_item = ["Contract Management", "Contract Data"]
apply_to_sub_items = false
inheritance = false
categories = [
{
name = "Contract Data"
attribute = "Status"
value = "Draft"
},
{
name = "Contract Data"
set = "Parties"
attribute = "Party Name"
row = 1
value = "Example Corp"
}
]
}
]
categoryAssignments:
- enabled: true
item:
- Contracts
- Templates
volume: 141
category_item:
- Contract Management
- Contract Data
apply_to_sub_items: false
inheritance: false
categories:
- name: Contract Data
attribute: Status
value: Draft
- name: Contract Data
set: Parties
attribute: Party Name
row: 1
value: Example Corp
securityClearances¶
securityClearances creates security clearance levels in Content Management Records Management. The clearances are created by running a Web Report in Content Management.
Each list element is a dictionary with these fields:
enabled(bool, optional, default =true) - switch to turn the payload element on or offlevel(str, mandatory) - security level value of the clearance (the level is passed as a string, e.g."10")name(str, mandatory) - name of the security clearancedescription(str, optional, default = empty) - description of the security clearance
supplementalMarkings¶
supplementalMarkings creates supplemental markings in Content Management Records Management. The markings are created by running a Web Report in Content Management.
Each list element is a dictionary with these fields:
enabled(bool, optional, default =true) - switch to turn the payload element on or offcode(str, mandatory) - code of the supplemental markingdescription(str, optional, default = empty) - description of the supplemental marking
recordsManagementSettings¶
recordsManagementSettings imports Records Management and Physical Objects settings into Content Management from settings files. Unlike most other sections, this section is a single dictionary (not a list) and has no enabled switch.
The settings files must be available in the custom settings directory of the Customizer (setting cust_settings_dir); the file names are resolved relative to it. All keys are optional; a key that is missing or set to an empty string is skipped. The import steps run in the order listed below.
records_management_system_settings(str, optional) - file name of the Records Management system settings to importrecords_management_codes(str, optional) - file name of the Records Management codes to importrecords_management_rsis(str, optional) - file name of the Records Management Retention Schedule Information (RSI) definitions to importphysical_objects_system_settings(str, optional) - file name of the Physical Objects system settings to importphysical_objects_codes(str, optional) - file name of the Physical Objects codes to importphysical_objects_locators(str, optional) - file name of the Physical Objects locators to importsecurity_clearance_codes(str, optional) - file name of the security clearance codes to import
recordsManagementSettings = {
records_management_system_settings = "rm_system_settings"
records_management_codes = "rm_codes"
records_management_rsis = "rm_rsis"
physical_objects_system_settings = "po_system_settings"
physical_objects_codes = "po_codes"
physical_objects_locators = "po_locators"
security_clearance_codes = "security_clearance_codes"
}
recordsManagementSettings:
records_management_system_settings: rm_system_settings
records_management_codes: rm_codes
records_management_rsis: rm_rsis
physical_objects_system_settings: po_system_settings
physical_objects_codes: po_codes
physical_objects_locators: po_locators
security_clearance_codes: security_clearance_codes
holds¶
holds creates Records Management holds in Content Management below the "Hold Maintenance" folder of the Records Management volume. If a hold with the same name already exists, it is skipped.
Each list element is a dictionary with these fields:
enabled(bool, optional, default =true) - switch to turn the payload element on or offname(str, mandatory) - name of the holdtype(str, mandatory) - type of the hold (e.g.Legal)group(str, optional) - name of a hold group (folder) below "Hold Maintenance" in which the hold is created. The group is created if it does not exist. Without a group the hold is created directly in "Hold Maintenance".comment(str, optional, default = empty) - comment for the holdalternate_id(str, optional) - alternate ID of the holddate_applied(str, optional) - date the hold is applied, formatYYYY-MM-DDTHH:mm:ss.date_to_remove(str, optional) - date the hold is suspended / removed, formatYYYY-MM-DDTHH:mm:ss
Bulk Load Customizing Syntax¶
For mass loading and generation of workspaces, documents, items and classifications from external data sources the customizing allows to specify bulk datasources, bulk workspaces, bulk workspace relationships, bulk documents, bulk items, and bulk classifications. The data sources will be loaded in an internal table representation (we use Pandas Data Frames for this).
bulkDatasources¶
Before you can bulk load workspaces, workspace relationships, or documents you have to declare the used data sources. bulkDatasources is a list of datasources. Each list element can include a switch called enabled to turn them on or off (the default is true). This switch can be controlled by a Terraform variable (or could just be false or true). First, a data source needs a type. Supported types are excel (Microsoft Excel workbooks), servicenow (ServiceNow REST API), otmm (OpenText Media Management REST API), otcs (OpenText Content Management REST API), pht (internal OpenText System for Product Master Data, REST API), json (JSON files), csv (comma-separated values), and xml (XML files, or whole directories / zip files of XML files). Based on the selected type data sources may have many specific fields to configure the specifics of the data source and define how to connect to the data source.
The following settings can be applied to all data source types:
cleansings(dictionary, optional, default = {}) to clean the values in defined columns of the data set. Each list item is a dictionary with these keys:upper(bool, optional, default =false) - convert complete string to upper caselower(bool, optional, default =false) - convert complete string to lower casecapitalize(bool, optional, default =false) - capitalize first character of stringtitle(bool, optional, default =false) - capitalize first character of each wordlength(int, optional, default = None)replacements(dict, optional, default ={}) - the keys are regular expressions and the values are replacement valuescolumns_to_drop(list, optional, default =[]) list of column names to remove from the data set (to black list those to delete)columns_to_keep(list, optional, default =[]) list of columns to keep in the data set and delete all others (to white list those to keep)columns_to_add(list, optional, default =[]) - each list item is a dictionary with these keys:source_column(str, mandatory) - name of the column the base value for the new column is taken fromname(str, mandatory) - name of the new columnreg_exp(str, optional, default = None)prefix(str, optional, default = "") - prefix to add to the new column valuesuffix(str, optional, default = "") - suffix to add to the new column valuelength(int, optional, default = None)group_chars(str, optional, default = None)group_separator(str, optional, default =.)columns_to_add_list(list, optional, default = []): add a new column with list values. Each payload item is a dictionary with these keys:source_columns(str, mandatory) - names of the columns from which row values are taken from to create the list of string valuesname(str, mandatory) - name of the new columncolumns_to_add_concat(list, optional, default = []): add a new column with concatenated values. Each payload item is a dictionary with these keys:source_columns(str, mandatory) - names of the columns from which row values are taken from to create the list of string valuesname(str, mandatory) - name of the new columnconcat_chars(str, optional, default = "") - concatenation characters, e.g. "-" or "."lower(bool, optional, default = False) - convert result to lower caseupper(bool, optional, default = False) - convert result to upper casecapitalize(bool, optional, default = False) - capitalize resulttitle(bool, optional, default = False) - convert result to title casecolumns_to_add_table(list, optional, default = []): add a new column with table values. Each payload item is a dictionary with these keys:source_columns(str, mandatory) - names of the columns from which row values are taken from to create a list of dictionary values. It is expected that the source columns already have list items or are strings with delimiter-separated values.name(str, mandatory) - name of the new columnlist_splitter(str, optional, default =,) Defines the delimiter for splitting strings from the source columns into a list.conditions(list, optional, default = []) - each list item is a dict with these keys:field(str, mandatory)value(str | bool | list, optional, default = None)equal(bool, optional): iftruetest for equality (this is the default), iffalsetest for non-equalityexplosions(list, optional, default = []) - each list item is a dict with these keys:explode_fields(str | list, mandatory)flatten_fields(list, optional, default =[])split_string_to_list(bool, optional, default = False)list_splitter(str, optional) - defines the delimiters for splitting strings in a list. Always set it ifsplit_string_to_lististrue.name_column(str, optional, default = None) - name of the column in the data source that determines the bulk item namesynonyms_column(str, optional, default = None)
CSV File specific settings:
csv_delimiter(str, optional) - value delimiter in the file - default is a commacsv_header_index(int, optional) - if the file has a header line this parameter specifies the index (0 = first line, this is the default)csv_column_names(list, optional) - if the file has no header line the column name can be specified as a list of stringscsv_use_columns(list, optional) - this list can either include integers (index of columns to keep), strings (names of columns to keep), or a list of boolean values (True = column is kept, False = column is dropped)
OpenText Content Management / Content Server specific settings (fields):
otcs_hostname(str, mandatory)otcs_protocol(str, optional, default =https)otcs_port(str, optional, default =443)otcs_basepath(str, optional, default =/cs/cs)otcs_username(str, mandatory)otcs_password(str, mandatory)otcs_thread_number(int, optional, default = BULK_THREAD_NUMBER)otcs_download_dir(str, optional, default =/data/contentserver)otcs_root_node_ids(int | list[int], mandatory)otcs_include_workspaces(bool, optional, default = True) - if workspace rows should be created in the data frameotcs_include_items(bool, optional, default = True) - if item rows should be created in the data frameotcs_include_workspace_metadata(bool, optional, default = True) - if metadata columns for workspaces should be created in the data frameotcs_include_item_metadata(bool, optional, default = True) - if metadata columns for items should be created in the data frameotcs_filter_workspace_depth(int, optional, default = 0) - 0 = workspaces are located immediately below given root nodeotcs_filter_workspace_subtypes(list, optional, default =[]) - 0 = folder subtypeotcs_filter_workspace_category(str, optional, default = None) - defines the category the workspace needs to have to pass the filterotcs_filter_workspace_attributes(dict | list, optional, default = None)set(str, optional, default = None) - name of the attribute setrow(int, optional, default = None) - row number (starting with 1) - only required for multi-value setsattribute(str, mandatory) - name of the attributevalue(str, mandatory) - value the attribute should have to pass the filterotcs_filter_item_depth(int, optional, default = None) - depth of the document under the given roototcs_filter_item_subtypes(list, optional, default =[]) - 0 = folder subtype, 144 = document subtypeotcs_filter_item_category(str, optional, default = None) - defines the category that the item needs to have to pass the filterotcs_filter_item_attributes(dict | list, optional, default = None)set(str, optional, default = None) - name of the attribute setrow(int, optional, default = None) - row number (starting with 1) - only required for multi-value setsattribute(str, mandatory) - name of the attributevalue(str, mandatory) - value the attribute should have to pass the filterotcs_filter_item_in_workspace(bool, optional, default = True) - defines whether or not items in workspace should also be filteredotcs_exclude_node_ids(list, optional, default = None) - list of Content Server IDs to exclude from loading / traversingotcs_download_documents(bool, optional, default = True) - defines whether or not documents should actually be downloadedotcs_skip_existing_downloads(bool, optional, default = True) - defines whether or not documents downloaded before and still exist in the filesystem should be downloaded once moreextract_zip(bool, optional, default = False) - defines whether or not zip files should be uncompressed and its content should be uploaded insteadotcs_use_numeric_category_identifier(bool, optional, default = True) - defines whether or not category IDs should be used in data frame columns. IfFalsethen a normalized category name will be used instead
ServiceNow specific settings (fields):
sn_base_url(str, mandatory) - ServiceNow base URLsn_auth_type(str, optional, default =basic) - authentication type of ServiceNowsn_username(str, optional, default = "") - user name used with ServiceNowsn_password(str, optional, default = "") - password of the provided usersn_client_id(str, optional, default = None) - client ID of ServiceNowsn_client_secret(str, optional, default = None) - client secret of ServiceNowsn_table_name(str, optional, default =u_kb_template_technical_article_public) - name of the table used for the Knowledge Base Articlessn_queries(list, mandatory) - list of queries to retrieve the Knowledge base articlessn_table_name(str, mandatory) - name of the ServiceNow database table for the querysn_query(str, mandatory) - query stringsn_thread_number(int, optional, default = BULK_THREAD_NUMBER)sn_download_dir(str, optional, default =/data/knowledgebase) - the directory in the file system where attachments from ServiceNow should be stored for further processingsn_skip_existing_downloads(bool, optional, default = True) - whether or not attachments that have been downloaded before should be reused
OpenText Media management specific settings (fields):
otmm_username(str, optional, default = "") - name of the user for the asset retrievalotmm_password(str, optional, default = "") - password of the given userotmm_client_id(str, optional, default = None) - client ID for authenticationotmm_client_secret(str, optional, default = None) - client secret for authenticationotmm_thread_number(int, optional, default = BULK_THREAD_NUMBER) - number of parallel running threadsotmm_download_dir(str, optional, default =/data/mediaassets) - directory in the customizer pod to temporarily store the asset filesotmm_business_unit_exclusions(list, optional, default =[]) - black list for Business Units to excludeotmm_business_unit_inclusions(list, optional, default =[]) - white list for Business Units to includeotmm_product_exclusions(list, optional, default =[]) - black list of products to excludeotmm_product_inclusions(list, optional, default =[]) - white list of products to include
OpenText Product Hierarchy Tracker (PHT) specific settings (fields):
pht_base_url(str, mandatory) - PHT base URLpht_username(str, optional, default = "") - name of the user for the data retrievalpht_password(str, optional, default = "") - password of the given userpht_business_unit_exclusions(list, optional, default =[]) - black list for Business Units to excludepht_business_unit_inclusions(list, optional, default =[]) - white list for Business Units to includepht_product_exclusions(list, optional, default =[]) - black list of products to excludepht_product_inclusions(list, optional, default =[]) - white list of products to includepht_product_category_exclusions(list, optional, default = [])pht_product_category_inclusions(list, optional, default = [])pht_product_status_exclusions(list, optional, default = [])pht_product_status_inclusions(list, optional, default = [])pht_product_attributes(list, optional, default = []) - a list of attribute names that should be extracted and added as columns to the data frame
Filesystem specific settings (fields):
root_folders(list, mandatory) - a list of paths to root folders that are traversed to load the data frame. The dataframe will have the following columns:filename,size,path,relative_path,download_dirand columns for each path part that are numbered like this:level <n>.
This is an example for a bulkDatasources definition:
bulkDatasources = [
{
enabled = true
name = "ntsb"
description = "NTSB Data Source from https://www.ntsb.gov"
type = "json"
json_files = ["/datasources/ntsb-2024-01.json", "/datasources/ntsb-2024-02.json", "/datasources/ntsb-1962-2023.json"]
# columns to keep. If empty we keep all columns
columns_to_keep = [
"cm_mkey",
"cm_ntsbNum",
"...",
]
# columns to drop. If empty we drop no columns
columns_to_drop = []
explosions = [
{
explode_fields = "cm_vehicles"
flatten_fields = ["make", "model", "operatorName"]
}
]
conditions= [
{
"field": "cm_vehicles_operatorName",
"value": [
"AIR CANADA",
"AIR CHINA",
"..."
],
"regex": false,
},
]
cleansings = {
"airportName": {
"upper": true
"replacements" : {
"-": " ", # replace hyphen with space
"/": " ", # replace slash with space
" AIRPORT$": "", # remove " AIRPORT" at the end of names
" AIRPOR$": "", # remove " AIRPOR" at the end of names
" ARPT$": "", # remove " ARPT" at the end of names
" AIRP$": "", # remove " AIRP" at the end of names
" A$": "", # remove " A" at the end of names (abbreviation for Airport)
}
}
}
}
]
bulkWorkspaces¶
To bulk load workspaces you can define a payload section bulkWorkspaces which can produce a large number of workspaces based on placeholders that are filled with data from a defined data source. Each list element can include a switch called enabled to turn them on or off (the default is true). This switch can be controlled by a Terraform variable (or could just be false or true). First, a data source needs a data_source that specifies the name of a data source in the bulkDatasources payload section.
These are the settings in a single bulk workspace list element:
enabled(bool, optional, default =true)type_name(str, mandatory) - type of the workspacedata_source(str, mandatory) - name of a data source item defined in thebulkDatasourcessection.force_reload(bool, optional, default =true) - enforce a reload of the data source, e.g. useful if data source has been modified before by column operations or explosionscopy_data_source(bool, optional, default =false) - to avoid side effects for repeated usage of the data sourceoperations(list, optional, default =["create"]) - list of operations to apply for workspaces:create,update,delete,recreate(any combination of these). "recreate" = delete existing + create newupdate_operations(list, optional, default =["name", "description", "categories", "nickname"]) - list of update operations to apply for workspaces if operationupdateis selected.explosions(list, optional, default =[]) - each list item is a dict with these keys:explode_fields(str | list, mandatory)flatten_fields(list, optional, default =[])split_string_to_list(bool, optional, default =false)list_splitter(str, optional, default =,) - defines the delimiters for splitting strings in a list.unique(list, optional, default =[]) - list of fields (columns) that should be unique -> deduplicationsort(list, optional, default =[]) - list of fields to sort the data frame byname(str, mandatory) - name of the workspace - can include placeholder surrounded by {...}name_alt(str, optional, default = None) - alternative name of the workspace (used ifnameis evaluated to empty string)description(str, optional, default = "") - can include placeholder surrounded by {...}description_alt(str, optional, default = None) - alternative description of the workspace (used ifdescriptionis evaluated to empty string)template_name(str, optional, default = take first template)categories(list, optional, default =[]) - each list item is a dictionary that may have these keys:name(str, mandatory)set(str, default = "")row(int, optional)attribute(str, mandatory)value(str, optional if value_field is specified, default = None)value_field(str, optional if value is specified, default = None) - can include placeholder surrounded by {...}value_type(str, optional, default =string) - possible values:string,datetime,listandtable. Iflistis selected, then string with delimiter-separated values will be converted to a list.attribute_mapping(dict, optional, default = None) - only relevant for value_type = "table" - defines a mapping from the data frame column names to the category attribute namesvalue_mapping(dict, optional, default = None) - dictionary keys are the original values and dictionary values are the mapped values. This makes most sense for values with a limited / fixed domain of possible valueslist_splitter(str, optional, default =;,) - only relevant for value_typelist. Defines the delimiter for splitting strings in a list.lookup_data_source(str, optional, default = None)lookup_data_failure_drop(bool, optional, default = false) - should we clear / drop values that cannot be looked up?is_key(bool, optional, default = false) - find workspace if name matching does not work (e.g. workspace name has changed in the data source since last run). For this we expect akeyvalue to be defined in the bulk workspace and one of the category / attribute item to be marked withis_key = true.external_create_date(str, optional, default = "")external_modify_date(str, optional, default = "")key(str, optional, default = None) - lookup value for workspaces other than the name. Works in combination withis_keyin thecategoriespayload.replacements(dict, optional, default ={}) - Each dictionary item has the field name as the dictionary key and a list of regular expressions as dictionary valuenickname(str, optional, default = None) - nickname of the workspace - can include placeholder surrounded by {...}nickname_alt(str, optional, default = None) - alternative nickname of the workspace (used ifnicknameis evaluated to empty string)conditions(list, optional, default =[]) - each list item is a dictionary that may have these keys:field(str, mandatory)value(str | bool | list, optional, default = None) - if no value is specified only the existence of the field is testedequal(bool, optional): if True test for equality (this is the default), if False test for non-equalityaviator_metadata(bool, optional, default =false) - Send request to FEME to embed the metadata for the workspace. Action will be performed after updates and creations.
This is an example for a bulkWorkspaces definitions:
bulkWorkspaces = [
{
data_source = "ntsb"
name = "{airportName} ({airportId})"
nickname = "ws_location_{airportName}_{airportId}"
description = ""
type_name = "Location"
template_name = "Location"
conditions = [
{
field = "{airportName}"
},
{
field = "{airportId}"
}
]
unique = ["airportName", "airportId"]
sort = ["airportName"] # sorting may help to avoid name clashes between threads
replacements = {} # no "local" replacements
},
{
data_source = "ntsb"
name = "{cm_vehicles.make}"
nickname = "ws_manufacturer_{cm_vehicles.make}"
description = ""
type_name = "Manufacturer"
template_name = "Manufacturer"
conditions = [
{
field = "{cm_mode}"
value = "Aviation"
},
{
field = "{cm_vehicles.make}"
}
]
unique = ["cm_vehicles_make"]
sort = ["cm_vehicles_make"] # sorting may help to avoid name clashes between threads
replacements = {} # no "local" replacements
},
{
data_source = "ntsb"
name = "{cm_vehicles.operatorName}"
nickname = "ws_operator_{cm_vehicles.operatorName}"
description = ""
type_name = "Operator"
template_name = "Operator"
conditions = [
{
field = "{cm_vehicles.operatorName}"
}
]
unique = ["cm_vehicles_operatorName"] # we must have an underscore here as this is a generated top-level field
sort = ["cm_vehicles_operatorName"] # sorting may help with avoiding name clashes between threads
replacements = {} # no "local" replacements
},
{
data_source = "ntsb"
name = "{cm_ntsbNum}"
nickname = "ws_incident_{cm_ntsbNum}"
description = ""
type_name = "Incident"
template_name = "Incident"
unique = ["cm_ntsbNum"] # the explosion may generate multiple lines for one NTSB number
replacements = {} # no "local" replacements
categories = [
{
name = "Incident"
set = ""
attribute = "Key"
value_field = "{cm_mkey}"
},
{
name = "Incident"
set = ""
attribute = "Status"
value_field = "{cm_completionStatus}"
},
{
name = "Incident"
set = ""
attribute = "Has Safety Recommendation"
value_field = "{cm_hasSafetyRec}"
},
{
name = "Incident"
set = ""
attribute = "Highest Injury Level"
value_field = "{cm_highestInjury}"
},
...
]
},
]
bulkWorkspaceRelationships¶
To bulk load workspace relationships you can define a payload section bulkWorkspaceRelationships which can produce a large number of workspace relationships based on placeholders that are filled with data from a defined data source.
Each list element can include a switch called enabled to turn them on or off (the default is true). This switch can be controlled by a Terraform variable (or could just be false or true).
In addition, a bulk workspace relationship needs a data_source that specifies the name of a data source in the bulkDatasources payload section. Then the from workspace name is either defined by from_workspace (which is the nickname) and the to workspace nickname is defined by to_workspace. Alternatively, the from and to workspaces can be determined by the combination of the type (from_workspace_type, to_workspace_type) and the name (from_workspace_name and to_workspace_name) of the workspaces. The type defines if the from workspace is the child or the parent in the relationship.
These are all the settings in a single bulk workspace relationship list element:
enabled(bool, optional, default = true)from_workspace(str, mandatory) - nickname of the workspace on the from side.from_workspace_type(str, optional, default = None) - type name of the workspace on the from side.from_workspace_name(str, optional, default = None) - name of the workspace on the from side.from_workspace_data_source(str, optional, default = None)from_sub_workspace_name(str, optional, default = None) - if the related workspace is a sub-workspacefrom_sub_workspace_path(list, optional, default = None) - the folder path under the main workspace where the sub-workspaces are locatedfrom_workspace_lookup_error(bool, optional, default = True) - whether or not an error should be logged if a relationship endpoint cannot be looked upto_workspace(str, mandatory) - nickname of the workspace on the to side.to_workspace_type(str, optional, default = None) - type name of the workspace on the to side.to_workspace_name(str, optional, default = None) - name of the workspace on the to side.to_workspace_data_source(str, optional, default = None)to_sub_workspace_name(str, optional, default = None) - if the related workspace is a sub-workspaceto_sub_workspace_path(list, optional, default = None) - the folder path under the main workspace where the sub-workspaces are locatedto_workspace_lookup_error(bool, optional, default = True) - whether or not an error should be logged if a relationship endpoint cannot be looked uptype(str, optional, default =child) - type of the relationship (defines if the from workspace is the parent or the child)data_source(str, mandatory)force_reload(bool, optional, default = true) - enforce a reload of the data source, e.g. useful if data source has been modified before by column operations or explosionscopy_data_source(bool, optional, default = false) - to avoid side effects for repeated usage of the data sourceexplosions(list, optional, default =[]) - each list item is a dict with these keys:explode_fields(str | list, mandatory)flatten_fields(list, optional, default =[])split_string_to_list(bool, optional, default =false)list_splitter(str, optional, default =,) - defines the delimiters for splitting strings in a list.unique(list, optional, default = [])sort(list, optional, default = [])thread_number(int, optional, default = BULK_THREAD_NUMBER)replacements(list, optional, default = None)conditions(list, optional, default = None)field(str, mandatory)value(str | bool | list, optional, default = None)equal(bool, optional): iftruethen test for equality (this is the default), iffalsetest for non-equality
This is an example for bulkWorkspaceRelationships definitions:
bulkWorkspaceRelationships = [
{
# Relationship between Incidents and Airports:
data_source = "ntsb"
from_workspace = "ws_incident_{cm_ntsbNum}"
to_workspace = "ws_location_{airportName}_{airportId}"
type = "parent"
conditions = [
{
field = "{airportName}"
},
{
field = "{airportId}"
}
]
unique = ["cm_ntsbNum", "airportName", "airportId"] # this is important to remove duplicates produced by explosions
sort = ["cm_ntsbNum"] # sorting may help to avoid name clashes between threads
replacements = {} # no "local" replacements
},
{
# Relationship between Incidents and Manufacturers:
data_source = "ntsb"
from_workspace = "ws_incident_{cm_ntsbNum}"
to_workspace = "ws_manufacturer_{cm_vehicles.make}"
type = "parent"
conditions = [
{
field = "{cm_vehicles.make}"
}
]
unique = ["cm_ntsbNum", "cm_vehicles_make"] # need to use the flattened field here
sort = ["cm_ntsbNum"] # sorting may help to avoid name clashes between threads
replacements = {} # no "local" replacements
},
{
# Relationship between Incidents and Airlines:
data_source = "ntsb"
from_workspace = "ws_incident_{cm_ntsbNum}"
to_workspace = "ws_operator_{cm_vehicles.operatorName}"
type = "parent"
conditions = [
{
field = "{cm_vehicles.operatorName}" # ensure we only process rows that have operatorName field
}
]
unique = ["cm_ntsbNum", "cm_vehicles_operatorName"] # need to use the flattened field here
sort = ["cm_ntsbNum"] # sorting may help to avoid name clashes between threads
replacements = {} # no "local" replacements
}
]
bulkDocuments¶
To bulk load documents you can define a payload section bulkDocuments which can upload a large number of documents based on placeholders that are filled with data from a defined data source. Each list element can include a switch called enabled to turn them on or off (the default is true). This switch can be controlled by a Terraform variable (or could just be false or true). First, a bulk document needs a data_source that specifies the name of a data source in the bulkDatasources payload section.
These are all the settings in a single bulk document list element:
enabled(bool, optional, default = true)data_source(str, mandatory)force_reload(bool, optional, default = true) - enforce a reload of the data source, e.g. useful if data source has been modified before by column operations or explosionscopy_data_source(bool, optional, default = false) - to avoid side effects for repeated usage of the data sourceexplosions(list of dicts, optional, default = [])explode_fields(str | list, mandatory)flatten_fields(list, optional, default = [])split_string_to_list(bool, optional, default = false)list_splitter(str, optional) - defines the delimiters for splitting strings in a list. Always set it ifsplit_string_to_lististrue.unique(list, optional, default = []) - list of fields (columns) that should be unique -> deduplicationsort(list, optional, default = []) - list of fields to sort the data frame byoperations(list, optional, default = ["create"]) - possible values:create,update,delete,recreateupdate_operations(list, optional, default =["name", "description", "categories", "version"]) - list of update operations to apply for documents ifupdateis included in operations (see above).name(str, mandatory) - can include placeholder surrounded by {...}name_alt(str, optional, default = None) - can include placeholder surrounded by {...}name_regex(str, optional, default = r"") - regex replacement for document names. The pattern and replacement are separated by pipe character |description(str, optional, default = None) - can include placeholder surrounded by {...}download_name(str, optional, default = name) - - can include placeholder surrounded by {...}download_name_wildcards(bool, optional, default = False) - defines if the download name includes wildcards, e.g. "*.pdf"nickname(str, optional, default = None) - can include placeholder surrounded by {...}download_url(str, optional, default = None)download_url_alt(str, optional, default = None)download_dir(str, optional, default = BULK_DOCUMENT_PATH)delete_download(bool, optional, default =true)file_extension(str, optional, default = "")file_extension_alt(str, optional, default =html)mime_type(str, optional, default =application/pdf)mime_type_alt(str, optional, default =text/html)categories(list, optional, default =[])name(str, mandatory)set(str, default = "")row(int, optional)attribute(str, mandatory)value(str, optional if value_field is specified, default = None)value_field(str, optional if value is specified, default = None) - can include placeholder surrounded by {...}value_type(str, optional, default =string) - possible values:string,datetime,list, andtable. If list then string with comma-separated values will be converted to a list.attribute_mapping(dict, optional, default = None) - only relevant for value typetable- defines a mapping from the data frame column names to the category attribute nameslist_splitter(str, optional, default =;,) - only relevant for value typelist. Defines the delimiter for splitting strings in a list.lookup_data_source(str, optional, default = None)lookup_data_failure_drop(bool, optional, default = false) - should we clear / drop values that cannot be looked up?is_key(bool, optional, default = false) - find document is old name. For this we expect akeyvalue to be defined for the bulk document and one of the category / attribute item to be marked withis_key = true.thread_number(int, optional, default = BULK_THREAD_NUMBER)external_create_date(str, optional, default = "")external_modify_date(str, optional, default = "")key(str, optional, default = None) - lookup key for documents other than the namedownload_wait_time(int, optional, default = 30)download_retries(int, optional, default = 2)replacements(list, optional, default =[])conditions(list, optional, default =[]) - all conditions must evaluate to truefield(str, mandatory)value(str | bool | list, optional, default = None)equal(bool, optional): iftruetest for equality (this is the default), iffalsetest for non-equalityworkspaces(list, optional, default =[]) - the workspaces the document should be uploaded toworkspace_name(str, mandatory)conditions(list, optional, default =[])field(str, mandatory)value(str | bool | list, optional, default = None)equal(bool, optional): iftruetest for equality (this is the default), iffalsetest for non-equality
workspace_type(str, mandatory)data_source(str, optional, default = None)workspace_folder(str, optional, default = "")workspace_path(list, optional, default =[])sub_workspace_type(str, optional, default = "")sub_workspace_name(str, optional, default = "")sub_workspace_template(str, optional, default = "")sub_workspace_folder(str, optional, default = "")sub_workspace_path(list, optional, default =[])
This is an example for bulkDocuments definitions:
bulkDocuments = [
{
data_source = "ntsb"
download_url = "https://data.ntsb.gov/carol-repgen/api/Aviation/ReportMain/GenerateNewestReport/{cm_mkey}/pdf"
download_dir = "/data/ntsb/incident-reports/"
name = "{cm_ntsbNum}"
file_extension = "pdf"
mime_type = "application/pdf"
download_name = "{cm_mkey}"
download_name_wildcards = false
delete_download = false
download_retries = 2
download_wait_time = 5 # wait to before retry in seconds
conditions = [
{
field = "{cm_mostRecentReportType}" # just check there's a field and any value
}
]
unique = ["cm_ntsbNum"] # make sure we don't have duplicates created by exploded bulkDataSource
sort = ["cm_ntsbNum"] # sorting may help to avoid name clashes between threads
replacements = {} # no "local" replacements
workspaces = [
{
workspace_name = "{cm_ntsbNum}"
workspace_type = "Incident"
workspace_folder = ""
},
{
workspace_name = "{airportName} ({airportId})"
workspace_type = "Location"
workspace_folder = "{cm_vehicles.operatorName}"
conditions = [
{
field = "{airportName}"
},
{
field = "{airportId}"
}
]
},
{
workspace_name = "{cm_vehicles.make}"
workspace_type = "Manufacturer"
workspace_folder = "{cm_vehicles.model}"
conditions = [
{
field = "{cm_vehicles.make}"
}
]
},
{
workspace_name = "{cm_vehicles.operatorName}"
workspace_type = "Operator"
conditions = [
{
field = "{cm_vehicles.operatorName}"
}
]
}
]
}
]
bulkItems¶
To bulk create items such as folders, shortcuts, or URL items, you can define a payload section bulkItems which can create a large number of items based on placeholders that are filled with data from a defined data source. Each bulkItems list element can include a switch called enabled to turn them on or off (the default is true). This switch can be controlled by a Terraform variable (or could just be false or true). First, a bulk item needs a data_source that specifies the name of a data source in the bulkDatasources payload section.
These are all the settings in a single bulk item list element:
enabled(bool, optional, default = true)data_source(str, mandatory)force_reload(bool, optional, default = true) - enforce a reload of the data source, e.g. useful if data source has been modified before by column operations or explosionscopy_data_source(bool, optional, default = false) - to avoid side effects for repeated usage of the data sourceexplosions(list of dicts, optional, default = [])explode_fields(str | list, mandatory)flatten_fields(list, optional, default = [])split_string_to_list(bool, optional, default = false)list_splitter(str, optional) - defines the delimiters for splitting strings in a list. Always set it ifsplit_string_to_lististrue.unique(list, optional, default = []) - list of fields (columns) that should be unique -> deduplicationsort(list, optional, default = []) - list of fields to sort the data frame byoperations(list, optional, default =["create"]) - possible values:create,update,delete,recreateupdate_operations(list, optional, default =["name", "description", "categories", "url"]) - list of update operations to apply for workspaces ifupdateis included in operations (see above).name(str, mandatory) - can include placeholder surrounded by {...}name_alt(str, optional, default = None) - can include placeholder surrounded by {...}name_regex(str, optional, default = r"") - regex replacement for document names. The pattern and replacement are separated by pipe character |description(str, optional, default = None) - can include placeholder surrounded by {...}nickname(str, optional, default = None) - can include placeholder surrounded by {...}categories(list, optional, default =[])name(str, mandatory)set(str, default = "")row(int, optional)attribute(str, mandatory)value(str, optional if value_field is specified, default = None)value_field(str, optional if value is specified, default = None) - can include placeholder surrounded by {...}value_type(str, optional, default =string) - possible values:string,datetime,list, andtable. If list then string with comma-separated values will be converted to a list.attribute_mapping(dict, optional, default = None) - only relevant for value typetable- defines a mapping from the data frame column names to the category attribute nameslist_splitter(str, optional, default =;,) - only relevant for value typelist. Defines the delimiter for splitting strings in a list.lookup_data_source(str, optional, default = None)lookup_data_failure_drop(bool, optional, default = false) - should we clear / drop values that cannot be looked up?is_key(bool, optional, default = false) - find document is old name. For this we expect akeyvalue to be defined for the bulk document and one of the category / attribute item to be marked withis_key = true.thread_number(int, optional, default = BULK_THREAD_NUMBER)external_create_date(str, optional, default = "")external_modify_date(str, optional, default = "")key(str, optional, default = None) - lookup key for documents other than the namereplacements(list, optional, default =[])conditions(list, optional, default =[]) - all conditions must evaluate to truefield(str, mandatory)value(str | bool | list, optional, default = None)equal(bool, optional): iftruetest for equality (this is the default), iffalsetest for non-equalityworkspaces(list, optional, default =[]) - the workspaces the document should be uploaded toworkspace_name(str, mandatory)conditions(list, optional, default =[])field(str, mandatory)value(str | bool | list, optional, default = None)equal(bool, optional): iftruetest for equality (this is the default), iffalsetest for non-equality
workspace_type(str, mandatory)data_source(str, optional, default = None)workspace_folder(str, optional, default = "")workspace_path(list, optional, default =[])sub_workspace_type(str, optional, default = "")sub_workspace_name(str, optional, default = "")sub_workspace_template(str, optional, default = "")sub_workspace_folder(str, optional, default = "")sub_workspace_path(list, optional, default =[])
This is an example for bulkItems definitions:
bulkItems = [
{
data_source = "ntsb"
name = "{cm_ntsbNum}"
type = 0 # the type of the item. 0 = Folder, 1 = Shortcut, 140 = URL
url = "" # the actual URL for an url item. Empty / irrelevant if type is not 140 = URL
original_nickname = "" # the nickname of the original item
original_path = [] # the top-down folder path (each folder or workspace name is a list item)
conditions = [
{
field = "{cm_mostRecentReportType}" # just check there's a field and any value
}
]
unique = ["cm_ntsbNum"] # make sure we don't have duplicates created by exploded bulkDataSource
sort = ["cm_ntsbNum"] # sorting may help to avoid name clashes between threads
replacements = {} # no "local" replacements
workspaces = [
{
workspace_name = "{cm_ntsbNum}"
workspace_type = "Incident"
workspace_folder = ""
},
{
workspace_name = "{airportName} ({airportId})"
workspace_type = "Location"
workspace_folder = "{cm_vehicles.operatorName}"
conditions = [
{
field = "{airportName}"
},
{
field = "{airportId}"
}
]
},
{
workspace_name = "{cm_vehicles.make}"
workspace_type = "Manufacturer"
workspace_folder = "{cm_vehicles.model}"
conditions = [
{
field = "{cm_vehicles.make}"
}
]
},
{
workspace_name = "{cm_vehicles.operatorName}"
workspace_type = "Operator"
conditions = [
{
field = "{cm_vehicles.operatorName}"
}
]
}
]
}
]
bulkClassifications¶
To bulk create classifications (items in the Classification Volume of Content Server) you can define a payload section bulkClassifications which can create, update or delete a large number of classifications based on placeholders that are filled with data from a defined data source. The rows of the data source are processed in parallel by multiple threads. Each list element can include a switch called enabled to turn them on or off (the default is true). This switch can be controlled by a Terraform variable (or could just be false or true). First, a bulk classification needs a data_source that specifies the name of a data source in the bulkDatasources payload section.
These are all the settings in a single bulk classification list element:
enabled(bool, optional, default =true) - switch to turn the payload element on or offdata_source(str, mandatory) - name of the data source in thebulkDatasourcespayload sectionforce_reload(bool, optional, default =true) - enforce a reload of the data source, e.g. useful if data source has been modified before by column operations or explosionscopy_data_source(bool, optional, default =false) - to avoid side effects for repeated usage of the data sourceexplosions(list of dicts, optional, default =[])explode_fields(str | list, mandatory) - the field(s) (columns) with list values to explode into multiple rowsflatten_fields(list, optional, default =[])split_string_to_list(bool, optional, default =false)list_splitter(str, optional, default =,) - defines the delimiters for splitting strings in a list.filters(list of dicts, optional, default =[]) - only keep the data rows that match all filter conditions. Filters are applied after the explosions and before sorting and deduplication. Each filter has afield(name of a column in the data source), avalue(str | list; if it is a list one of the values must match) and optionallyequal(bool, default =true),regex(bool, default =false) andenabled(bool, default =true).sort(list, optional, default =[]) - list of fields (columns) to sort the data frame byunique(list, optional, default =[]) - list of fields (columns) that should be unique -> deduplication. Deduplication is done after sorting and always keeps the first matching row.operations(list, optional, default =["create"]) - possible values:create,update,delete,recreate.deleteis only executed ifconditions_deleteis defined.recreatedeletes an existing classification (with purge) and creates it again.update_operations(list, optional, default =["name", "description", "categories", "nickname"]) - list of update operations to apply for classifications ifupdateis included inoperationspath(list, optional, default =[]) - the top-down path of parent classifications in the Classification Volume under which the classification is created (each list element is a classification name, can include placeholder surrounded by {...}). If the path is empty (or if a placeholder cannot be resolved) the classification is created directly in the Classification Volume. Missing path elements are only created automatically ifkeyis used.name(str, mandatory) - name of the classification, can include placeholder surrounded by {...}. Rows where the name cannot be resolved are skipped.name_alt(str, optional, default = None) - alternative name that is used ifnamecannot be resolved, can include placeholder surrounded by {...}description(str, optional, default = None) - can include placeholder surrounded by {...}description_alt(str, optional, default = None) - alternative description that is used ifdescriptioncannot be resolved, can include placeholder surrounded by {...}nickname(str, optional, default = None) - nickname of the classification, can include placeholder surrounded by {...}. The value is converted to lower case and spaces and hyphens are replaced by underscores.nickname_alt(str, optional, default = None) - alternative nickname that is used ifnicknamecannot be resolved, can include placeholder surrounded by {...}key(str, optional, default = None) - lookup key for classifications other than the name, can include placeholder surrounded by {...}. If a key is defined then one of the category attributes must be marked withis_key = true. An existing classification is then found by the value of this attribute (and not by its name), which allows to rename classifications.external_create_date(str, optional, default = None) - can include placeholder surrounded by {...}external_modify_date(str, optional, default = None) - can include placeholder surrounded by {...}. Forupdateoperations the classification is only updated if this date is newer than the modification date of the existing classification.thread_number(int, optional, default = value of the environment variableBULK_THREAD_NUMBER, or1) - number of parallel threadsreplacements(dict, optional, default = None) - replacements that are applied to the values read from the data source. The dictionary key is the field name and the value is a list of replacement rules.conditions(list, optional, default =[]) - all conditions must evaluate to true, otherwise the data row is skippedfield(str, mandatory) - can include placeholder surrounded by {...}value(str | bool | list, optional, default = None) - if not specified only the existence of a value for the field is tested. If it is a list one of the list values must match.equal(bool, optional, default =true): iftruetest for equality, iffalsetest for non-equalityconditions_create(list, optional, default =[]) - same syntax asconditions. If defined and not met by a data row, thecreateandrecreateoperations are not executed for this row.conditions_update(list, optional, default =[]) - same syntax asconditions. If defined and not met by a data row, theupdateoperation is not executed for this row.conditions_delete(list, optional, default =[]) - same syntax asconditions. If not defined or not met by a data row, thedeleteoperation is not executed for this row.categories(list, optional, default =[]) - categories and attributes to set on the classificationname(str, mandatory) - name of the categoryset(str, optional, default = "") - name of the attribute set (if the attribute is part of a set)row(int, optional) - row number for attributes in multi-row setsattribute(str, mandatory) - name of the attributevalue(str, optional ifvalue_fieldis specified, default = None)value_field(str, optional ifvalueis specified, default = None) - can include placeholder surrounded by {...}value_field_alt(str, optional, default = None) - alternative value field that is used ifvalue_fieldcannot be resolved, can include placeholder surrounded by {...}value_type(str, optional, default =string) - possible values:string,datetime,list, andtable. Iflistthen a string with delimiter-separated values will be converted to a list.attribute_mapping(dict, optional, default = None) - only relevant for value typetable- defines a mapping from the data frame column names to the category attribute nameslist_splitter(str, optional, default =;,) - only relevant for value typelist. Defines the delimiters for splitting strings in a list.value_mapping(dict, optional, default = None) - maps original values to the values to be written to the attributesort_multi_values(bool, optional, default =false) - sort the values of a multi-value attribute alphabeticallylookup_data_source(str, optional, default = None) - name of a data source used to look up a synonym for the valuelookup_data_failure_drop(bool, optional, default =false) - should we clear / drop values that cannot be looked up?is_key(bool, optional, default =false) - marks the attribute that stores the value of thekeyof the bulk classification
If a classification (with the same name or, if key is used, with the same key) already exists it is skipped unless update, delete or recreate is requested. If a nickname is defined and a classification with this nickname already exists, then the classification is skipped as well (unless update or delete is requested). Classifications that were successfully processed are recorded so that a repeated run does not try to process them again.
This is an example for bulkClassifications definitions:
bulkClassifications = [
{
enabled = true
data_source = "contract-types"
path = ["Contracts", "{region}"]
name = "{contractType}"
name_alt = "{contractTypeCode}"
description = "Contract type {contractType}"
nickname = "{contractTypeCode}"
operations = ["create", "update"]
update_operations = ["name", "description"]
unique = ["contractTypeCode"]
sort = ["contractTypeCode"]
conditions = [
{
field = "{contractType}"
}
]
conditions_update = [
{
field = "{status}"
value = ["changed", "new"]
}
]
categories = [
{
name = "Classification Attributes"
attribute = "Code"
value_field = "{contractTypeCode}"
is_key = true
}
]
key = "{contractTypeCode}"
}
]
bulkClassifications:
- enabled: true
data_source: contract-types
path:
- Contracts
- "{region}"
name: "{contractType}"
name_alt: "{contractTypeCode}"
description: Contract type {contractType}
nickname: "{contractTypeCode}"
operations:
- create
- update
update_operations:
- name
- description
unique:
- contractTypeCode
sort:
- contractTypeCode
conditions:
- field: "{contractType}"
conditions_update:
- field: "{status}"
value:
- changed
- new
categories:
- name: Classification Attributes
attribute: Code
value_field: "{contractTypeCode}"
is_key: true
key: "{contractTypeCode}"
Advanced Customizing Syntax¶
For advanced use cases that are not covered by OpenText Content Management or OTDS APIs, there are additional customizing capabilities. This includes calling SAP Remote Function Calls (RFC), executing commands in the Kubernetes Pods or triggering web hooks (HTTP POST requests):
kubernetes¶
This payload type allows to apply commands via the Kubernetes API. Currently the actions restart and execPodCommands are supported.
action="restart"¶
restart can be used with type (deployment, statefulset, pod). For deployment and statefulset a rolling deployment will be triggered. In case of "pod" it will be deleted and it is expected that the Kubernetes API automatically recreates it. This will not work if the pod was created as a standalone instance.
action="execPodCommands"¶
execPodCommands is used to execute a Linux command inside a Kubernetes pod using the Kubernetes API (similar to what kubectl exec does). This may be handy to influence / change some of the intrinsics of the pods. If enabled evaluates to true then the command will be called during the customization process. The pod_name must match the technical name of the pod in the Kubernetes deployment (you can get the pod names with kubectl get pods). command is a list of the command terms and parameters. The first element is typically the Linux shell that is used for executing the command and the second parameter is typically -c if the command is run in non-interactive mode. interactive defines if the command is run interactively or not. The default is to run the command non-interactively. Only for longer running commands you should prefer to run the command interactively.
kubernetes = [
{
enabled = true
action = "execPodCommands"
description = "Test"
pod_name = "otcs-admin-0"
command = ["/bin/sh", "-c", "touch /tmp/python_was_here"]
interactive = false
},
{
enabled = true
action = "restart"
type = "deployment"
name = "otdsws"
},
{
enabled = true
action = "restart"
type = "statefulset"
name = "otcs-frontend"
}
]
execPodCommands (deprecated)¶
use kubernetes with action execPodCommands
execPodCommands is used to execute a Linux command inside a Kubernetes pod using the Kubernetes API (similar to what kubectl exec does). This may be handy to influence / change some of the intrinsics of the pods. If enabled evaluates to true then the command will be called during the customization process. The pod_name must match the technical name of the pod in the Kubernetes deployment (you can get the pod names with kubectl get pods). command is a list of the command terms and parameters. The first element is typically the Linux shell that is used for executing the command and the second parameter is typically -c if the command is run in non-interactive mode. interactive defines if the command is run interactively or not. The default is to run the command non-interactively. Only for longer running commands you should prefer to run the command interactively.
execCommands¶
execCommands is used to execute a command in the local customizer pod. command is a list of the command terms and parameters. The first element is typically the Linux shell that is used for executing the command and the second parameter is typically -c.
execDatabaseCommands¶
execDatabaseCommands is used to execute commands in a database. If enabled evaluates to true then the database command set is active.
Each item in the execDatabaseCommands list consists of a database connection db_connection and a list of commands db_commands to execute in that database. Each command can have a list of associated parameters params. If params is not empty then the command must have placeholders given by %s that are replaced by the parameters from the params list in the given ordering.
webHooks¶
webHooks and webHooksPost are used to call (HTTP request) defined URLs that may trigger certain activities as webhooks. webHooks is called at the beginning of the customization process and webHooksPost is called at the end.
If enabled evaluates to true then the webhook is active.
url defines the URL of the web hook. method can be one of the typical HTTP request types (POST, GET, PUT, ...). If it is omitted the default is POST. description should describe the purpose of the web hook. The parameters payload and headers are maps (dictionaries) of name, value pairs. These are passed as additional header or body values to the HTTP request.
webHooks = [
{
enabled = var.enable_sap
url = "https://.../start_sap"
method = "POST"
description = "Start SAP S/4HANA Web Hook"
payload = {
parameter = "value"
}
headers = {} # if empty a standard header will be set
}
]
webHooksPost = [
{
enabled = var.enable_sap
url = "https://.../stop_sap"
method = "POST"
description = "Stop SAP S/4HANA Web Hook"
payload = {}
headers = {} # if empty a standard header will be set
}
]
webHooks:
- description: Start SAP S/4HANA Web Hook
enabled: ${var.enable_sap}
headers: {}
method: POST
payload:
parameter: value
url: https://.../start_sap
webHooksPost:
- description: Stop SAP S/4HANA Web Hook
enabled: ${var.enable_sap}
headers: {}
method: POST
payload: {}
url: https://.../stop_sap
sapRFCs¶
The sapRFCs payload defines a list of SAP Remote Function Calls (RFC) that are called to automate things in SAP S/4HANA. If enabled evaluates to true then the RFC will be called during the customization process. name is the technical SAP name of the RFC. description is optional and is just informative. If the RFC requires parameters they can be passed via the parameters block (name, value pairs).
sapRFCs = [
{
enabled = var.enable_sap
name = "SM02_ADD_MESSAGE"
description = "Write message into SAP message center"
parameters = {
"MESSAGE" = "Start processing Terrarium RFC calls..."
}
},
{
enabled = var.enable_sap
name = "ZFM_GECKO_RFC_CR_UPD_ALL_WKSP"
description = "Create workspace for all SAP Customers (KNA1)"
parameters = {
"OBJECTTYPE" = "KNA1"
"OBJECTKEY" = ""
"SYNC" = ""
}
}
]
sapRFCs:
- description: Write message into SAP message center
enabled: ${var.enable_sap}
name: SM02_ADD_MESSAGE
parameters:
MESSAGE: Start processing Terrarium RFC calls...
- description: Create workspace for all SAP Customers (KNA1)
enabled: ${var.enable_sap}
name: ZFM_GECKO_RFC_CR_UPD_ALL_WKSP
parameters:
OBJECTKEY: ''
OBJECTTYPE: KNA1
SYNC: ''
Browser Automations¶
browserAutomations is a list of browser automation for things that can only be
automated via the web user interface. Each list element is a dict with these keys:
enabled(bool, optional, default = True)name(str, mandatory)description(str, optional)base_url(str, mandatory)user_name(str, optional)password(str, optional)wait_time(float, optional, default = 45.0) - wait time in secondswait_until(str, optional) - the page load / navigationwait untilstrategy. Possible values:load,networkidle,domcontentloadedheadless(bool, optional) - run the browser without a visible window. Defaults to the global Customizer setting.browser(str, optional) - the browser to use:webkit,chromiumorfirefox. Defaults to the environment variableBROWSER, orwebkitif it is not set.debug(bool, optional, default = False) - if True take screenshots and save to customizer podautomations(list, mandatory)dependent(bool, optional, default = true) - decide if current automation step is dependent on the previous step. If dependent = True and previous step failed this step is skipped.type(str, optional, default = "") - possible types:login,get_page,click_elem,set_elem,check_elempage(str, optional, default = "") - the page-specific part of the URL. Will be concatenated with thebase_urlselector(str, optional, default = "") - the selector (search pattern) for the page elementselector_type(str, optional, default = "id") - the type of the selector - eitherid,name,css,xpath,role,text,title,label,placeholder,altrole_type(str, optional, default = "") - the ARIA role of an element. Only relevant for find =role.scroll_to_element(bool, optional, default = true) - scroll to the element before clicking it - for typeclick_elemonly. Should actually not be necessary as locators should scroll automatically.value(str, optional, default = "") - the new value of element. Relevant for type =set_elem.user_field(str, optional, default = "") - the name of the HTML field holding the user name - only for typelogin.password_field(str, optional, default = "") - the name of the HTML field holding the password - only for typelogin.iframe: name of the iframe if the elem is inside an iframepress_enter: simulate pressing the "Enter" key after setting the elem value - for typeset_elemonlytyping(bool, optional) - deciding if to simulate keyboard input - this is required for many type-ahead fields to work - for typeset_elemonlyexact_match(bool, optional) - deciding if the element should be identified with an exact matchhover_only(bool, optional) - deciding if instead of clicking the element only a mouse over hovering should be simulated - for typeclick_elemonlywait_until(str, optional, default = "") - an automation-step specific value forwait_until(see above)volume(int, optional, default = 141 (Enterprise Volume)) - the OTCS volume ID. Only relevant for type =get_page.path(list, optional, default = []) - a top-down list of folder / workspace names. Only relevant for type =get_page.navigation(bool, optional, default = False) - whether or not the click issues a navigation event. Relevant only for type =click_elem.popup_window(bool, optional) - deciding if the click will popup a new browser window - for typeclick_elemonlyclose_window(bool, optional) - deciding if the click will close the current window - for typeclick_elemonlycheckbox_state(bool, optional, default = None) - defines the desired state of a checkbox element (True = checked, False = unchecked)attribute(str, optional, default = "") - the attribute name of an HTML element. Relevant only for type =check_elem.substring(bool, optional, default = False) - whether or not a string comparison should consider substrings. Relevant only for type =check_elem.min_count(int, optional, default = 1) - defines how many elements should be found at a minimum by type =check_elem.want_exist(bool, optional, default = True) - defines for type =check_elemif the existence or non-existence should be checked.iframe(str, optional) - name of the iframe tag if the element is inside an iframe.exact_match- if the element name should be an exact matchregex(bool, optional) - is the name to be interpreted as a regular expression?
testAutomations¶
testAutomations is processed by exactly the same logic as Browser Automations. It is intended for browser-based (Playwright) tests of the deployed system rather than for configuration tasks. Each list element supports the same fields as in Browser Automations (enabled, name, description, base_url, user_name, password, wait_time, wait_until, debug, automations and all automation step fields); please refer to that section instead of repeating them here.
The only differences are:
- In the log output the elements are called "Test automation" instead of "Browser automation".
- The processing status of the section is tracked separately under the section name
testAutomations, so it is run (or skipped after a successful run) independently ofbrowserAutomations.
testAutomations = [
{
enabled = true
name = "Check Login"
description = "Verify that a user can log in"
base_url = "https://content.example.com"
user_name = "jdoe"
password = "secret"
automations = [
{
type = "login"
page = "/otcs/cs.exe"
},
{
type = "check_elem"
selector = "Enterprise"
selector_type = "text"
}
]
}
]
Search Aviator Customizing Syntax¶
avtsRepositories¶
avtsRepositories is used to define Search Aviator repositories.
These are all the settings in a single repository list element:
enabled: true/falsename: Name of the Repository needs to be uniquetype: AVTS repository type:- Extended ECM
- Documentum
OpenText Content Management specific values¶
otcs_url: URL of Content Server (OTCS), e.g.https://otcs.domain.tld/cs/csotcs_api_url: URL of Content Server (OTCS), e.g.https://otcs.domain.tld/cs/csusername: Username for Content Server crawlingpassword: Password for the crawling usernode_id: Node ID of the Content Server root folder
Documentum specific values¶
to be done
avtsRepositories = [
{
enabled = true
name = "OpenText Content Management"
type = "Extended ECM"
otcs_url = "https://otcs.domain.tld/cs/cs"
otcs_api_url = "http://otcs-frontend/cs/cs"
username = "admin"
password = "********"
node_id = 2000
start = true
},
{
enabled = true
name = "Microsoft Teams"
start = true
type = "MSTeams"
client_id = "XXXX"
tenant_id = "XXXX"
certificate_file = "/certificates/certificate.pfx"
certificate_password = "XXXX"
index_attachments = true
index_call_recordings = true
index_message_replies = true
index_user_chats = true
},
{
enabled = true
name = "SharePoint"
start = true
type = "SharePoint"
client_id = "XXXX"
tenant_id = "XXXX"
certificate_file = "/certificates/certificate.pfx"
certificate_password = "XXXX"
sharepoint_url_type = "SiteCollection"
sharepoint_url = "https://xxx.sharepoint.com"
sharepoint_mysite_url = "https://xxx.sharepoint.com/sites/Innovate/"
sharepoint_admin_url = "https://xxx.admin.com"
index_user_profiles = false
}
]
avtsQuestions¶
avtsQuestions sets the list of sample questions that Aviator Search proposes to users. It is a single dictionary (not a list). The questions are sent to Aviator Search after authentication; existing proposed questions are replaced by the given list.
The dictionary has these fields:
enabled(bool, optional, default =true) - switch to turn the payload section on or offquestions(list of str, optional, default =[]) - the sample questions to be proposed in Aviator Search
Content Aviator Customizing Syntax¶
embeddings¶
embeddings triggers the embedding of metadata (and optionally documents and images) into Content Aviator, using the FEME embedding tool. The section can also be named feme in payloadSections. It is processed for each list element; the target nodes can be given by node ID, by nickname or by workspace type.
Each list element is a dictionary with these fields:
enabled(bool, optional, default =true) - switch to turn the payload element on or offid(int, optional) - ID of the node to embed. If set,nicknameandworkspace_typesare ignored.nickname(str, optional) - nickname of the node to embed. Only used ifidis not set.workspace_types(str or list of str, optional) - name(s) of workspace types. All workspace instances of these types are embedded. Only used if neitheridnornicknameresolves to a node.wait_for_completion(bool, optional, default =true) - wait until the embedding has finishedcrawl(bool, optional, default =false) - run the task as a "crawl" instead of an "index"document_metadata(bool, optional, default =false) - embed the metadata of documents. The legacy keydocumentsis used ifdocument_metadatais not present.workspace_metadata(bool, optional, default =false) - embed the metadata of workspaces. The legacy keyworkspacesis used ifworkspace_metadatais not present.images(bool, optional, default =false) - embed images
aviatorMcpServers¶
aviatorMcpServers creates MCP (Model Context Protocol) server configurations in Content Aviator. The section is only processed if Content Aviator is configured; otherwise a warning is logged and it is skipped.
Each list element is a dictionary with these fields:
enabled(bool, optional, default =true) - switch to turn the payload element on or off. The value is also passed to Content Aviator as the "active" state of the server.name(str, mandatory) - unique name of the MCP servertransport(str, optional, default =streamable_http) - transport type:streamable_http,sseorstdiourl(str, mandatory for transportstreamable_httpandsse) - URL of the MCP servercommand(str, mandatory for transportstdio) - command to start the MCP serverargs(list of str, optional) - arguments for thestdiocommandtool_scope(str, optional) - where the tools of the server are available:defaultorcustomauth_schema(dict, optional) - authentication configuration, passed as is to Content Aviator
aviatorMcpTools¶
aviatorMcpTools registers additional MCP tools (Content Aviator agents) in Content Aviator. Tools that are already registered are skipped. The section is only processed if Content Aviator is configured; otherwise a warning is logged and it is skipped.
Each list element is a dictionary with these fields:
enabled(bool, optional, default =true) - switch to turn the payload element on or offname(str, mandatory) - name of the tool to register
AppWorks Platform Customizing Syntax¶
appworks¶
appworks configures OpenText AppWorks Platform organizations. For each organization the Customizer first (optionally) sets up the OTDS resource, access role, license and Kubernetes configuration, then creates the AppWorks workspaces, publishes their projects and finally creates entities (categories, priorities, case types, customers, cases). The section requires that OTDS, Content Server, AppWorks Platform and Kubernetes access are configured.
Each list element is a dictionary with these fields:
enabled(bool, optional, default =true) - switch to turn the payload element on or offorganization(str, mandatory) - name of the AppWorks organizationresource_config(bool, optional, default =false) - iftrue, the OTDS resource<organization>is created (if missing), the Content Server and admin partitions are added to the OTDS access roleAccess to <organization>, the AppWorks license is assigned (if a license file is available), the organization configuration in the Kubernetes config map is updated and the AppWorks stateful set is restarted. Iffalse, this part is skipped.workspaces(list, optional) - list of AppWorks workspaces to create and synchronize. If missing, no workspaces or entities are processed for the organization.workspace_id(str, mandatory) - ID of the workspacename(str, mandatory) - name of the workspacepath(str, mandatory) - directory in the AppWorks pod that contains the project artifacts. For a newly created workspace the content of this directory is copied into the workspace.projects(list, optional) - list of projects in the workspace that are publishedname(str, mandatory) - name of the projectdocumentId(str, mandatory) - document ID of the project
entities(list, optional) - list of entities to create in the organization. Existing categories, priorities, case types and customers (identified by name) are skipped.type(str, mandatory) - one ofcategory,priority,caseType,customer,casename(str, mandatory for all types exceptcase) - name of the entitydescription(str, optional, default ="") - description (typescategory,priority,caseType,case)status(int, optional, default =1) - status of the entity (typescategory,priority,caseType)prefix(str, only for typecategory) - case prefix of the categorysub_entities(list, optional, only for typecategory) - sub categories. Each element hastype(must besubCategory),name,description(optional, default ="") andstatus(optional, default =1).legal_business_name(str, optional, default ="") - only for typecustomertrading_name(str, optional, default ="") - only for typecustomersubject(str, mandatory for typecase) - subject of the casecategory(str, optional) - name of an existing category. Only for typecase.sub_category(str, optional) - name of a sub category of the category. Only for typecase.priority(str, optional) - name of an existing priority. Only for typecase.case_type(str, optional) - name of an existing case type. Only for typecase.customer(str, optional) - name of an existing customer. Only for typecase.loan_amount(int, optional, default =1) - only for typecaseloan_duration_in_month(int, optional, default =2) - loan duration in months. Only for typecase.
appworks = [
{
enabled = true
organization = "contracts"
resource_config = true
workspaces = [
{
workspace_id = "contractsWorkspace"
name = "Contract Management"
path = "/opt/appworks/projects/contracts"
projects = [
{
name = "ContractApp"
documentId = "0a1b2c3d-1111-2222-3333-444455556666"
}
]
}
]
entities = [
{
type = "category"
name = "Loans"
description = "Loan cases"
prefix = "LN"
sub_entities = [
{
type = "subCategory"
name = "Personal Loans"
}
]
},
{
type = "priority"
name = "High"
},
{
type = "caseType"
name = "Standard"
},
{
type = "customer"
name = "Example Corp"
legal_business_name = "Example Corporation Ltd."
trading_name = "Example"
},
{
type = "case"
subject = "Loan request Example Corp"
category = "Loans"
sub_category = "Personal Loans"
priority = "High"
case_type = "Standard"
customer = "Example Corp"
loan_amount = 10000
loan_duration_in_month = 12
}
]
}
]
appworks:
- enabled: true
organization: contracts
resource_config: true
workspaces:
- workspace_id: contractsWorkspace
name: Contract Management
path: /opt/appworks/projects/contracts
projects:
- name: ContractApp
documentId: 0a1b2c3d-1111-2222-3333-444455556666
entities:
- type: category
name: Loans
description: Loan cases
prefix: LN
sub_entities:
- type: subCategory
name: Personal Loans
- type: priority
name: High
- type: caseType
name: Standard
- type: customer
name: Example Corp
legal_business_name: Example Corporation Ltd.
trading_name: Example
- type: case
subject: Loan request Example Corp
category: Loans
sub_category: Personal Loans
priority: High
case_type: Standard
customer: Example Corp
loan_amount: 10000
loan_duration_in_month: 12
Knowledge Discovery Customizing Syntax¶
nifi¶
nifi uploads Apache NiFi flows (process groups) to OpenText Knowledge Discovery and sets their parameters. It requires that Knowledge Discovery is configured. If a flow with the same name already exists, it is not uploaded again and not started; only its parameters are updated.
Each list element is a dictionary with these fields:
enabled(bool, optional, default =true) - switch to turn the payload element on or offname(str, mandatory) - name of the NiFi flow (process group)file(str, mandatory) - path to the flow definition file (JSON) that is uploaded to NiFiposition_x(float, optional, default =0.0) - X position of the flow on the NiFi canvasposition_y(float, optional, default =0.0) - Y position of the flow on the NiFi canvasstart(bool, optional, default =false) - iftrue, all processors of a newly uploaded flow are started and its controller services are enabledparameters(list, optional, default =[]) - list of parameters to set in the flow. Each element has these fields:component(str, mandatory) - name of the NiFi component that holds the parametername(str, mandatory) - name of the parametervalue(str, mandatory) - value of the parameter. An empty value is treated as missing.description(str, optional, default ="") - description of the parametersensitive(bool, optional, default =false) - whether the parameter is a sensitive value (it is not written to the log)
nifi = [
{
enabled = true
name = "Document Ingestion"
file = "/payload/nifi/document-ingestion.json"
position_x = 100.0
position_y = 200.0
start = true
parameters = [
{
component = "Document Ingestion Parameters"
name = "source_url"
value = "https://content.example.com"
description = "URL of the content source"
},
{
component = "Document Ingestion Parameters"
name = "api_password"
value = "secret"
sensitive = true
}
]
}
]
nifi:
- enabled: true
name: Document Ingestion
file: /payload/nifi/document-ingestion.json
position_x: 100.0
position_y: 200.0
start: true
parameters:
- component: Document Ingestion Parameters
name: source_url
value: https://content.example.com
description: URL of the content source
- component: Document Ingestion Parameters
name: api_password
value: secret
sensitive: true