pyxecm 2.0.0__py3-none-any.whl → 2.0.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pyxecm might be problematic. Click here for more details.

Files changed (50) hide show
  1. pyxecm/__init__.py +2 -1
  2. pyxecm/avts.py +79 -33
  3. pyxecm/customizer/api/app.py +45 -796
  4. pyxecm/customizer/api/auth/__init__.py +1 -0
  5. pyxecm/customizer/api/{auth.py → auth/functions.py} +2 -64
  6. pyxecm/customizer/api/auth/router.py +78 -0
  7. pyxecm/customizer/api/common/__init__.py +1 -0
  8. pyxecm/customizer/api/common/functions.py +47 -0
  9. pyxecm/customizer/api/{metrics.py → common/metrics.py} +1 -1
  10. pyxecm/customizer/api/common/models.py +21 -0
  11. pyxecm/customizer/api/{payload_list.py → common/payload_list.py} +6 -1
  12. pyxecm/customizer/api/common/router.py +72 -0
  13. pyxecm/customizer/api/settings.py +25 -0
  14. pyxecm/customizer/api/terminal/__init__.py +1 -0
  15. pyxecm/customizer/api/terminal/router.py +87 -0
  16. pyxecm/customizer/api/v1_csai/__init__.py +1 -0
  17. pyxecm/customizer/api/v1_csai/router.py +87 -0
  18. pyxecm/customizer/api/v1_maintenance/__init__.py +1 -0
  19. pyxecm/customizer/api/v1_maintenance/functions.py +100 -0
  20. pyxecm/customizer/api/v1_maintenance/models.py +12 -0
  21. pyxecm/customizer/api/v1_maintenance/router.py +76 -0
  22. pyxecm/customizer/api/v1_otcs/__init__.py +1 -0
  23. pyxecm/customizer/api/v1_otcs/functions.py +61 -0
  24. pyxecm/customizer/api/v1_otcs/router.py +179 -0
  25. pyxecm/customizer/api/v1_payload/__init__.py +1 -0
  26. pyxecm/customizer/api/v1_payload/functions.py +179 -0
  27. pyxecm/customizer/api/v1_payload/models.py +51 -0
  28. pyxecm/customizer/api/v1_payload/router.py +499 -0
  29. pyxecm/customizer/browser_automation.py +567 -324
  30. pyxecm/customizer/customizer.py +204 -430
  31. pyxecm/customizer/guidewire.py +907 -43
  32. pyxecm/customizer/k8s.py +243 -56
  33. pyxecm/customizer/m365.py +104 -15
  34. pyxecm/customizer/payload.py +1943 -885
  35. pyxecm/customizer/pht.py +19 -2
  36. pyxecm/customizer/servicenow.py +22 -5
  37. pyxecm/customizer/settings.py +9 -6
  38. pyxecm/helper/xml.py +69 -0
  39. pyxecm/otac.py +1 -1
  40. pyxecm/otawp.py +2104 -1535
  41. pyxecm/otca.py +569 -0
  42. pyxecm/otcs.py +202 -38
  43. pyxecm/otds.py +35 -13
  44. {pyxecm-2.0.0.dist-info → pyxecm-2.0.2.dist-info}/METADATA +6 -32
  45. pyxecm-2.0.2.dist-info/RECORD +76 -0
  46. {pyxecm-2.0.0.dist-info → pyxecm-2.0.2.dist-info}/WHEEL +1 -1
  47. pyxecm-2.0.0.dist-info/RECORD +0 -54
  48. /pyxecm/customizer/api/{models.py → auth/models.py} +0 -0
  49. {pyxecm-2.0.0.dist-info → pyxecm-2.0.2.dist-info}/licenses/LICENSE +0 -0
  50. {pyxecm-2.0.0.dist-info → pyxecm-2.0.2.dist-info}/top_level.txt +0 -0
@@ -138,8 +138,8 @@ class Customizer:
138
138
  self.settings.m365.client_id,
139
139
  )
140
140
  self.logger.debug(
141
- "Microsoft 365 Client Secret = %s",
142
- self.settings.m365.client_secret,
141
+ "Microsoft 365 Client Secret = <sensitive>",
142
+ # self.settings.m365.client_secret,
143
143
  )
144
144
  self.logger.info(
145
145
  "Microsoft 365 Domain = %s",
@@ -166,8 +166,8 @@ class Customizer:
166
166
  self.settings.m365.sharepoint_app_client_id,
167
167
  )
168
168
  self.logger.debug(
169
- "Microsoft 365 SharePoint App Client Secret = %s",
170
- self.settings.m365.sharepoint_app_client_secret,
169
+ "Microsoft 365 SharePoint App Client Secret = <sensitive>",
170
+ # self.settings.m365.sharepoint_app_client_secret,
171
171
  )
172
172
 
173
173
  m365_object = M365(
@@ -397,37 +397,37 @@ class Customizer:
397
397
  """
398
398
 
399
399
  self.logger.info(
400
- "Aviator Search Base URL = %s",
400
+ "Aviator Search Base URL = %s",
401
401
  self.settings.avts.base_url,
402
402
  )
403
403
  self.logger.info(
404
- "Aviator Search OTDS URL = %s",
405
- self.settings.avts.otds_url,
404
+ "Aviator Search OTDS URL = %s",
405
+ str(self.settings.otds.url),
406
406
  )
407
407
  self.logger.info(
408
- "Aviator Search Client ID = %s",
408
+ "Aviator Search Client ID = %s",
409
409
  self.settings.avts.client_id,
410
410
  )
411
411
  self.logger.debug(
412
- "Aviator Search Client Secret = %s",
412
+ "Aviator Search Client Secret = %s",
413
413
  self.settings.avts.client_secret,
414
414
  )
415
415
  self.logger.info(
416
- "Aviator Search User ID = %s",
416
+ "Aviator Search User ID = %s",
417
417
  self.settings.avts.username,
418
418
  )
419
419
  self.logger.debug(
420
- "Aviator Search User Password = %s",
420
+ "Aviator Search User Password = %s",
421
421
  self.settings.avts.password,
422
422
  )
423
423
 
424
424
  return AVTS(
425
- otds_url=str(self.settings.avts.otds_url),
426
425
  base_url=str(self.settings.avts.base_url),
427
426
  client_id=self.settings.avts.client_id,
428
427
  client_secret=self.settings.avts.client_secret,
429
428
  username=self.settings.avts.username,
430
429
  password=self.settings.avts.password,
430
+ otds_url=str(self.settings.otds.url),
431
431
  logger=self.logger,
432
432
  )
433
433
 
@@ -606,6 +606,7 @@ class Customizer:
606
606
  password=self.settings.otds.password.get_secret_value(),
607
607
  otds_ticket=self.settings.otds.ticket,
608
608
  bind_password=self.settings.otds.bind_password.get_secret_value(),
609
+ admin_partition=self.settings.otds.admin_partition,
609
610
  logger=self.logger,
610
611
  )
611
612
 
@@ -651,12 +652,12 @@ class Customizer:
651
652
  """
652
653
 
653
654
  self.logger.info("Connection parameters OTAC:")
654
- self.logger.info("OTAC URL = %s", str(self.settings.otac.url))
655
- self.logger.info("OTAC URL internal = %s", str(self.settings.otac.url_internal))
656
- self.logger.info("OTAC Admin User = %s", self.settings.otac.username)
657
- self.logger.debug("OTAC Admin Password = %s", self.settings.otac.password)
655
+ self.logger.info("OTAC URL = %s", str(self.settings.otac.url))
656
+ self.logger.info("OTAC URL internal = %s", str(self.settings.otac.url_internal))
657
+ self.logger.info("OTAC Admin User = %s", self.settings.otac.username)
658
+ self.logger.debug("OTAC Admin Password = %s", self.settings.otac.password)
658
659
  self.logger.info(
659
- "OTAC Known Server = %s",
660
+ "OTAC Known Server = %s",
660
661
  (self.settings.otac.known_server if self.settings.otac.known_server != "" else "<not configured>"),
661
662
  )
662
663
 
@@ -686,9 +687,9 @@ class Customizer:
686
687
  cert_type="ARC",
687
688
  )
688
689
  if not response:
689
- self.logger.error("Failed to enable OTAC certificate for Extended ECM!")
690
+ self.logger.error("Failed to enable OTAC certificate for OTCS!")
690
691
  else:
691
- self.logger.info("Successfully enabled OTAC certificate for Extended ECM!")
692
+ self.logger.info("Successfully enabled OTAC certificate for OTCS!")
692
693
 
693
694
  # is there a known server configured for Archive Center (to sync content with)
694
695
  if otac_object and self.settings.otac.known_server != "":
@@ -778,18 +779,16 @@ class Customizer:
778
779
  self.settings.otcs.feme_uri,
779
780
  )
780
781
 
781
- self.logger.debug("Checking if OTCS object has already been initialized")
782
-
783
782
  otds_ticket = self.otds_object.cookie()["OTDSTicket"] if self.otds_object else None
784
783
  otcs_object = OTCS(
785
- url.scheme,
786
- url.host,
787
- url.port,
788
- self.settings.otcs.url.scheme + "://" + self.settings.otcs.url.host,
789
- self.settings.otcs.username,
790
- self.settings.otcs.password.get_secret_value(),
791
- self.settings.otcs.partition,
792
- self.settings.otcs.resource_name,
784
+ protocol=url.scheme,
785
+ hostname=url.host,
786
+ port=url.port,
787
+ public_url=self.settings.otcs.url.scheme + "://" + self.settings.otcs.url.host,
788
+ username=self.settings.otcs.username,
789
+ password=self.settings.otcs.password.get_secret_value(),
790
+ user_partition=self.settings.otcs.partition,
791
+ resource_name=self.settings.otcs.resource_name,
793
792
  otds_ticket=otds_ticket,
794
793
  base_path=self.settings.otcs.base_path,
795
794
  feme_uri=self.settings.otcs.feme_uri,
@@ -814,21 +813,31 @@ class Customizer:
814
813
  otcs_cookie = otcs_object.authenticate()
815
814
  self.logger.info("OTCS is ready now.")
816
815
 
816
+ # Now we should be able to get the OTCS resource ID from OTDS:
817
+ otcs_resource = self.otds_object.get_resource(
818
+ self.settings.otcs.resource_name,
819
+ )
820
+ if not otcs_resource or "resourceID" not in otcs_resource:
821
+ self.logger.error(
822
+ "Cannot get OTCS resource ID from OTDS for resource name -> '%s'!", self.settings.otcs.resource_name
823
+ )
824
+ return otcs_object
825
+ otcs_resource_id = otcs_resource["resourceID"]
826
+ otcs_object.set_resource_id(resource_id=otcs_resource_id)
827
+ self.logger.info(
828
+ "OTCS has resource ID -> '%s' for resource name -> '%s'", otcs_resource_id, self.settings.otcs.resource_name
829
+ )
830
+
817
831
  if "OTCS_RESSOURCE_ID" not in self.settings.placeholder_values:
818
- self.settings.placeholder_values["OTCS_RESSOURCE_ID"] = self.otds_object.get_resource(
819
- self.settings.otcs.resource_name,
820
- )["resourceID"]
832
+ self.settings.placeholder_values["OTCS_RESSOURCE_ID"] = otcs_resource_id
821
833
  self.logger.debug(
822
834
  "Placeholder values after OTCS init -> %s",
823
835
  self.settings.placeholder_values,
824
836
  )
825
837
 
826
838
  if self.settings.otawp.enabled:
827
- otcs_resource = self.otds_object.get_resource(
828
- self.settings.otcs.resource_name,
829
- )
830
- otcs_resource["logoutURL"] = (
831
- f"{self.settings.otawp.public_protocol}://{self.settings.otawp.public_url}/home/system/wcp/sso/sso_logout.htm"
839
+ otcs_resource["logoutURL"] = "{}://{}/home/system/wcp/sso/sso_logout.htm".format(
840
+ self.settings.otawp.public_protocol, self.settings.otawp.public_url
832
841
  )
833
842
  otcs_resource["logoutMethod"] = "GET"
834
843
 
@@ -896,14 +905,14 @@ class Customizer:
896
905
  )
897
906
 
898
907
  otiv_license = self.otds_object.add_license_to_resource(
899
- self.settings.otiv.license_file,
900
- self.settings.otiv.product_name,
901
- self.settings.otiv.product_description,
902
- otiv_resource["resourceID"],
908
+ path_to_license_file=self.settings.otiv.license_file,
909
+ product_name=self.settings.otiv.product_name,
910
+ product_description=self.settings.otiv.product_description,
911
+ resource_id=otiv_resource["resourceID"],
903
912
  )
904
913
  if not otiv_license:
905
914
  self.logger.info(
906
- "Couldn't apply license -> %s for product -> %s. Intelligent Viewing may not be deployed!",
915
+ "Couldn't apply license -> %s for product -> '%s'. Intelligent Viewing may not be deployed!",
907
916
  self.settings.otiv.license_file,
908
917
  self.settings.otiv.product_name,
909
918
  )
@@ -1007,6 +1016,7 @@ class Customizer:
1007
1016
  "OTAWP Enabled = %s",
1008
1017
  str(self.settings.otawp.enabled),
1009
1018
  )
1019
+ self.logger.info("OTAWP URL = %s", self.settings.otawp.public_url)
1010
1020
  self.logger.info(
1011
1021
  "OTAWP Resource = %s",
1012
1022
  self.settings.otawp.resource_name,
@@ -1016,7 +1026,8 @@ class Customizer:
1016
1026
  self.settings.otawp.access_role_name,
1017
1027
  )
1018
1028
  self.logger.info("OTAWP Admin User = %s", self.settings.otawp.username)
1019
- self.logger.debug("OTAWP Password = %s", self.settings.otawp.password)
1029
+ self.logger.debug("OTAWP Password = %s", self.settings.otawp.password)
1030
+ self.logger.info("OTAWP Organization = %s", self.settings.otawp.organization)
1020
1031
  self.logger.info("OTAWP K8s Stateful Set = %s", self.settings.k8s.sts_otawp)
1021
1032
  self.logger.info("OTAWP K8s Config Map = %s", self.settings.k8s.cm_otawp)
1022
1033
 
@@ -1025,6 +1036,8 @@ class Customizer:
1025
1036
  self.settings.otcs.resource_name,
1026
1037
  )
1027
1038
 
1039
+ organization = "system"
1040
+
1028
1041
  # Loop to wait for OTCS to create its OTDS resource
1029
1042
  # (we need it to update the AppWorks K8s Config Map):
1030
1043
  otcs_resource = self.otds_object.get_resource(self.settings.otcs.resource_name)
@@ -1049,223 +1062,15 @@ class Customizer:
1049
1062
  "OTDS resource -> '%s' for AppWorks Platform does not yet exist. Creating...",
1050
1063
  self.settings.otawp.resource_name,
1051
1064
  )
1052
- # Create a Python dict with the special payload we need for AppWorks:
1053
- additional_payload = {}
1054
- additional_payload["connectorid"] = "rest"
1055
- additional_payload["resourceType"] = "rest"
1056
- user_attribute_mapping = [
1057
- {
1058
- "sourceAttr": ["oTExternalID1"],
1059
- "destAttr": "__NAME__",
1060
- "mappingFormat": "%s",
1061
- },
1062
- {
1063
- "sourceAttr": ["displayname"],
1064
- "destAttr": "DisplayName",
1065
- "mappingFormat": "%s",
1066
- },
1067
- {"sourceAttr": ["mail"], "destAttr": "Email", "mappingFormat": "%s"},
1068
- {
1069
- "sourceAttr": ["oTTelephoneNumber"],
1070
- "destAttr": "Telephone",
1071
- "mappingFormat": "%s",
1072
- },
1073
- {
1074
- "sourceAttr": ["oTMobile"],
1075
- "destAttr": "Mobile",
1076
- "mappingFormat": "%s",
1077
- },
1078
- {
1079
- "sourceAttr": ["oTFacsimileTelephoneNumber"],
1080
- "destAttr": "Fax",
1081
- "mappingFormat": "%s",
1082
- },
1083
- {
1084
- "sourceAttr": ["oTStreetAddress,l,st,postalCode,c"],
1085
- "destAttr": "Address",
1086
- "mappingFormat": "%s%n%s %s %s%n%s",
1087
- },
1088
- {
1089
- "sourceAttr": ["oTCompany"],
1090
- "destAttr": "Company",
1091
- "mappingFormat": "%s",
1092
- },
1093
- {
1094
- "sourceAttr": ["ds-pwp-account-disabled"],
1095
- "destAttr": "AccountDisabled",
1096
- "mappingFormat": "%s",
1097
- },
1098
- {
1099
- "sourceAttr": ["oTExtraAttr9"],
1100
- "destAttr": "IsServiceAccount",
1101
- "mappingFormat": "%s",
1102
- },
1103
- {
1104
- "sourceAttr": ["custom:proxyConfiguration"],
1105
- "destAttr": "ProxyConfiguration",
1106
- "mappingFormat": "%s",
1107
- },
1108
- {
1109
- "sourceAttr": ["c"],
1110
- "destAttr": "Identity-CountryOrRegion",
1111
- "mappingFormat": "%s",
1112
- },
1113
- {
1114
- "sourceAttr": ["gender"],
1115
- "destAttr": "Identity-Gender",
1116
- "mappingFormat": "%s",
1117
- },
1118
- {
1119
- "sourceAttr": ["displayName"],
1120
- "destAttr": "Identity-DisplayName",
1121
- "mappingFormat": "%s",
1122
- },
1123
- {
1124
- "sourceAttr": ["oTStreetAddress"],
1125
- "destAttr": "Identity-Address",
1126
- "mappingFormat": "%s",
1127
- },
1128
- {
1129
- "sourceAttr": ["l"],
1130
- "destAttr": "Identity-City",
1131
- "mappingFormat": "%s",
1132
- },
1133
- {
1134
- "sourceAttr": ["mail"],
1135
- "destAttr": "Identity-Email",
1136
- "mappingFormat": "%s",
1137
- },
1138
- {
1139
- "sourceAttr": ["givenName"],
1140
- "destAttr": "Identity-FirstName",
1141
- "mappingFormat": "%s",
1142
- },
1143
- {
1144
- "sourceAttr": ["sn"],
1145
- "destAttr": "Identity-LastName",
1146
- "mappingFormat": "%s",
1147
- },
1148
- {
1149
- "sourceAttr": ["initials"],
1150
- "destAttr": "Identity-MiddleNames",
1151
- "mappingFormat": "%s",
1152
- },
1153
- {
1154
- "sourceAttr": ["oTMobile"],
1155
- "destAttr": "Identity-Mobile",
1156
- "mappingFormat": "%s",
1157
- },
1158
- {
1159
- "sourceAttr": ["postalCode"],
1160
- "destAttr": "Identity-PostalCode",
1161
- "mappingFormat": "%s",
1162
- },
1163
- {
1164
- "sourceAttr": ["st"],
1165
- "destAttr": "Identity-StateOrProvince",
1166
- "mappingFormat": "%s",
1167
- },
1168
- {
1169
- "sourceAttr": ["title"],
1170
- "destAttr": "Identity-title",
1171
- "mappingFormat": "%s",
1172
- },
1173
- {
1174
- "sourceAttr": ["physicalDeliveryOfficeName"],
1175
- "destAttr": "Identity-physicalDeliveryOfficeName",
1176
- "mappingFormat": "%s",
1177
- },
1178
- {
1179
- "sourceAttr": ["oTFacsimileTelephoneNumber"],
1180
- "destAttr": "Identity-oTFacsimileTelephoneNumber",
1181
- "mappingFormat": "%s",
1182
- },
1183
- {
1184
- "sourceAttr": ["notes"],
1185
- "destAttr": "Identity-notes",
1186
- "mappingFormat": "%s",
1187
- },
1188
- {
1189
- "sourceAttr": ["oTCompany"],
1190
- "destAttr": "Identity-oTCompany",
1191
- "mappingFormat": "%s",
1192
- },
1193
- {
1194
- "sourceAttr": ["oTDepartment"],
1195
- "destAttr": "Identity-oTDepartment",
1196
- "mappingFormat": "%s",
1197
- },
1198
- {
1199
- "sourceAttr": ["birthDate"],
1200
- "destAttr": "Identity-Birthday",
1201
- "mappingFormat": "%s",
1202
- },
1203
- {
1204
- "sourceAttr": ["cn"],
1205
- "destAttr": "Identity-UserName",
1206
- "mappingFormat": "%s",
1207
- },
1208
- {
1209
- "sourceAttr": ["Description"],
1210
- "destAttr": "Identity-UserDescription",
1211
- "mappingFormat": "%s",
1212
- },
1213
- {
1214
- "sourceAttr": ["oTTelephoneNumber"],
1215
- "destAttr": "Identity-Phone",
1216
- "mappingFormat": "%s",
1217
- },
1218
- {
1219
- "sourceAttr": ["displayName"],
1220
- "destAttr": "Identity-IdentityDisplayName",
1221
- "mappingFormat": "%s",
1222
- },
1223
- ]
1224
- additional_payload["userAttributeMapping"] = user_attribute_mapping
1225
- group_attribute_mapping = [
1226
- {
1227
- "sourceAttr": ["cn"],
1228
- "destAttr": "__NAME__",
1229
- "mappingFormat": '%js:function format(name) { return name.replace(/&/g,"-and-"); }',
1230
- },
1231
- {
1232
- "sourceAttr": ["description"],
1233
- "destAttr": "Description",
1234
- "mappingFormat": "%s",
1235
- },
1236
- {
1237
- "sourceAttr": ["description"],
1238
- "destAttr": "Identity-Description",
1239
- "mappingFormat": "%s",
1240
- },
1241
- {
1242
- "sourceAttr": ["displayName"],
1243
- "destAttr": "Identity-DisplayName",
1244
- "mappingFormat": "%s",
1245
- },
1246
- ]
1247
- additional_payload["groupAttributeMapping"] = group_attribute_mapping
1248
- additional_payload["connectorName"] = "REST (Generic)"
1249
- additional_payload["pcCreatePermissionAllowed"] = "true"
1250
- additional_payload["pcModifyPermissionAllowed"] = "true"
1251
- additional_payload["pcDeletePermissionAllowed"] = "false"
1252
- additional_payload["connectionParamInfo"] = [
1253
- {
1254
- "name": "fBaseURL",
1255
- "value": "http://appworks:8080/home/system/app/otdspush",
1256
- },
1257
- {"name": "fUsername", "value": self.settings.otawp.username},
1258
- {
1259
- "name": "fPassword",
1260
- "value": self.settings.otawp.password.get_secret_value(),
1261
- },
1262
- ]
1263
-
1264
1065
  awp_resource = self.otds_object.add_resource(
1265
1066
  name=self.settings.otawp.resource_name,
1266
1067
  description="AppWorks Platform",
1267
1068
  display_name="AppWorks Platform",
1268
- additional_payload=additional_payload,
1069
+ additional_payload=OTAWP.resource_payload(
1070
+ org_name=organization,
1071
+ username=self.settings.otawp.username,
1072
+ password=self.settings.otawp.password.get_secret_value(),
1073
+ ),
1269
1074
  )
1270
1075
  else:
1271
1076
  self.logger.info(
@@ -1287,60 +1092,74 @@ class Customizer:
1287
1092
  self.settings.placeholder_values,
1288
1093
  )
1289
1094
 
1290
- self.logger.info(
1291
- "Update AppWorks Kubernetes Config Map with OTDS resource IDs...",
1292
- )
1293
-
1294
- config_map = self.k8s_object.get_config_map(self.settings.k8s.cm_otawp)
1295
- if not config_map:
1296
- self.logger.error(
1297
- "Failed to retrieve AppWorks Kubernetes Config Map -> %s",
1298
- self.settings.k8s.cm_otawp,
1095
+ # Check if Kubernetes is available. Actually that should always be the case...
1096
+ if self.k8s_object:
1097
+ self.logger.info(
1098
+ "Update AppWorks Kubernetes Config Map with OTDS resource IDs...",
1299
1099
  )
1300
- else:
1301
- solution = yaml.safe_load(config_map.data["solution.yaml"])
1302
1100
 
1303
- # Change values as required
1304
- solution["platform"]["organizations"]["system"]["otds"]["resourceId"] = awp_resource_id
1305
- solution["platform"]["content"]["ContentServer"]["contentServerUrl"] = (
1306
- f"{self.settings.otcs.url!s}{self.settings.otcs.base_path}"
1307
- )
1308
- solution["platform"]["content"]["ContentServer"]["contentServerSupportDirectoryUrl"] = (
1309
- f"{self.settings.otcs.url!s}/cssupport"
1310
- )
1311
- solution["platform"]["content"]["ContentServer"]["otdsResourceId"] = otcs_resource_id
1312
- solution["platform"]["authenticators"]["OTDS_auth"]["publicLoginUrl"] = (
1313
- str(self.settings.otds.url) + "/otdsws/login"
1314
- )
1315
- solution["platform"]["security"]["contentSecurityPolicy"] = "frame-ancestors 'self' " + str(
1316
- self.settings.otcs.url,
1317
- )
1318
- config_map.data["solution.yaml"] = yaml.dump(solution)
1319
- result = self.k8s_object.replace_config_map(
1320
- self.settings.k8s.cm_otawp,
1321
- config_map.data,
1322
- )
1323
- if result:
1324
- self.logger.info("Successfully updated AppWorks solution YAML.")
1101
+ config_map = self.k8s_object.get_config_map(config_map_name=self.settings.k8s.cm_otawp)
1102
+ if not config_map:
1103
+ self.logger.error(
1104
+ "Failed to retrieve AppWorks Kubernetes config map -> '%s'",
1105
+ self.settings.k8s.cm_otawp,
1106
+ )
1325
1107
  else:
1326
- self.logger.error("Failed to update AppWorks Solution YAML.")
1327
- self.logger.debug("Solution YAML for AppWorks -> %s", solution)
1108
+ self.logger.info(
1109
+ "Update Kubernetes config map for AppWorks organization -> '%s' with OTDS resource IDs...",
1110
+ organization,
1111
+ )
1112
+ solution = yaml.safe_load(config_map.data["solution.yaml"])
1328
1113
 
1329
- self.logger.info("Scale AppWorks Kubernetes Stateful Set to 1...")
1330
- self.k8s_object.scale_stateful_set(
1331
- sts_name=self.settings.k8s.sts_otawp,
1332
- scale=1,
1333
- )
1114
+ # Change values as required
1115
+ solution["platform"]["organizations"][organization]["otds"]["resourceId"] = awp_resource_id
1116
+ solution["platform"]["content"]["ContentServer"]["contentServerUrl"] = (
1117
+ f"{self.settings.otcs.url!s}{self.settings.otcs.base_path}"
1118
+ )
1119
+ solution["platform"]["content"]["ContentServer"]["contentServerSupportDirectoryUrl"] = (
1120
+ f"{self.settings.otcs.url!s}/cssupport"
1121
+ )
1122
+ solution["platform"]["content"]["ContentServer"]["otdsResourceId"] = otcs_resource_id
1123
+ solution["platform"]["authenticators"]["OTDS_auth"]["publicLoginUrl"] = (
1124
+ str(self.settings.otds.url) + "/otdsws/login"
1125
+ )
1126
+ solution["platform"]["security"]["contentSecurityPolicy"] = "frame-ancestors 'self' " + str(
1127
+ self.settings.otcs.url,
1128
+ )
1129
+ config_map.data["solution.yaml"] = yaml.dump(solution)
1130
+ result = self.k8s_object.replace_config_map(
1131
+ config_map_name=self.settings.k8s.cm_otawp,
1132
+ config_map_data=config_map.data,
1133
+ )
1134
+ if result:
1135
+ self.logger.info(
1136
+ "Successfully updated AppWorks solution YAML for organization -> '%s'.",
1137
+ organization,
1138
+ )
1139
+ else:
1140
+ self.logger.error(
1141
+ "Failed to update AppWorks solution YAML for organization -> '%s'!",
1142
+ organization,
1143
+ )
1144
+ self.logger.debug("Solution YAML for AppWorks organization -> '%s': %s", organization, solution)
1145
+
1146
+ self.logger.info("Scale AppWorks Kubernetes stateful set -> '%s' to 1...", self.settings.k8s.sts_otawp)
1147
+ self.k8s_object.scale_stateful_set(
1148
+ sts_name=self.settings.k8s.sts_otawp,
1149
+ scale=1,
1150
+ )
1151
+ else:
1152
+ self.logger.warning("Kubernetes not initialized. Cannot configure AppWorks Kubernetes Config Map!")
1334
1153
 
1335
1154
  # Add the OTCS Admin user to the AppWorks Access Role in OTDS
1336
1155
  self.otds_object.add_user_to_access_role(
1337
- "Access to " + self.settings.otawp.resource_name,
1338
- "otadmin@otds.admin",
1156
+ access_role="Access to " + self.settings.otawp.resource_name,
1157
+ user_id="otadmin@otds.admin",
1339
1158
  )
1340
1159
 
1341
1160
  # Loop to wait for OTCS to create its OTDS user partition:
1342
1161
  otcs_partition = self.otds_object.get_partition(
1343
- self.settings.otcs.partition,
1162
+ name=self.settings.otcs.partition,
1344
1163
  show_error=False,
1345
1164
  )
1346
1165
  while otcs_partition is None:
@@ -1351,27 +1170,27 @@ class Customizer:
1351
1170
 
1352
1171
  time.sleep(30)
1353
1172
  otcs_partition = self.otds_object.get_partition(
1354
- self.settings.otcs.partition,
1173
+ name=self.settings.otcs.partition,
1355
1174
  show_error=False,
1356
1175
  )
1357
1176
 
1358
1177
  # Add the OTDS user partition for OTCS to the AppWorks Platform Access Role in OTDS.
1359
1178
  # This will effectvely sync all OTCS users with AppWorks Platform:
1360
1179
  self.otds_object.add_partition_to_access_role(
1361
- self.settings.otawp.access_role_name,
1362
- self.settings.otcs.partition,
1180
+ access_role=self.settings.otawp.access_role_name,
1181
+ partition=self.settings.otcs.partition,
1363
1182
  )
1364
1183
 
1365
1184
  # Add the OTDS admin partition to the AppWorks Platform Access Role in OTDS.
1366
1185
  self.otds_object.add_partition_to_access_role(
1367
- self.settings.otawp.access_role_name,
1368
- self.settings.otds.admin_partition,
1186
+ access_role=self.settings.otawp.access_role_name,
1187
+ partition=self.settings.otds.admin_partition,
1369
1188
  )
1370
1189
 
1371
1190
  # Set Group inclusion for Access Role for OTAWP to "True":
1372
1191
  self.otds_object.update_access_role_attributes(
1373
- self.settings.otawp.access_role_name,
1374
- [{"name": "pushAllGroups", "values": ["True"]}],
1192
+ name=self.settings.otawp.access_role_name,
1193
+ attribute_list=[{"name": "pushAllGroups", "values": ["True"]}],
1375
1194
  )
1376
1195
 
1377
1196
  # Add ResourceID User to OTDSAdmin to allow push
@@ -1381,92 +1200,23 @@ class Customizer:
1381
1200
  )
1382
1201
 
1383
1202
  # Allow impersonation for all users:
1384
- self.otds_object.impersonate_resource(self.settings.otawp.resource_name)
1385
-
1386
- # Add SPS license for OTAWP
1387
- # check if the license file exists, otherwise skip for versions pre 24.1
1388
- if os.path.isfile(self.settings.otawp.license_file):
1389
- self.logger.info(
1390
- "Found OTAWP license file -> '%s', assiging it to ressource '%s'...",
1391
- self.settings.otawp.license_file,
1392
- self.settings.otawp.resource_name,
1393
- )
1394
-
1395
- otawp_license = self.otds_object.add_license_to_resource(
1396
- self.settings.otawp.license_file,
1397
- self.settings.otawp.product_name,
1398
- self.settings.otawp.product_description,
1399
- awp_resource["resourceID"],
1400
- )
1401
- if not otawp_license:
1402
- self.logger.error(
1403
- "Couldn't apply license -> '%s' for product -> '%s' to OTDS resource -> '%s'",
1404
- self.settings.otawp.license_file,
1405
- self.settings.otawp.product_name,
1406
- awp_resource["resourceID"],
1407
- )
1408
- else:
1409
- self.logger.info(
1410
- "Successfully applied license -> '%s' for product -> '%s' to OTDS resource -> '%s'",
1411
- self.settings.otawp.license_file,
1412
- self.settings.otawp.product_name,
1413
- awp_resource["resourceID"],
1414
- )
1203
+ self.otds_object.impersonate_resource(resource_name=self.settings.otawp.resource_name)
1415
1204
 
1416
- # Assign AppWorks license to Content Server Members Partiton and otds.admin:
1417
- for partition_name in ["otds.admin", self.settings.otcs.partition]:
1418
- if self.otds_object.is_partition_licensed(
1419
- partition_name=partition_name,
1420
- resource_id=awp_resource["resourceID"],
1421
- license_feature="USERS",
1422
- license_name=self.settings.otawp.product_name,
1423
- ):
1424
- self.logger.info(
1425
- "Partition -> '%s' is already licensed for -> '%s' (%s)",
1426
- partition_name,
1427
- self.settings.otawp.product_name,
1428
- "USERS",
1429
- )
1430
- else:
1431
- assigned_license = self.otds_object.assign_partition_to_license(
1432
- partition_name,
1433
- awp_resource["resourceID"],
1434
- "USERS",
1435
- self.settings.otawp.product_name,
1436
- )
1437
- if not assigned_license:
1438
- self.logger.error(
1439
- "Partition -> '%s' could not be assigned to license -> '%s' (%s)",
1440
- partition_name,
1441
- self.settings.otawp.product_name,
1442
- "USERS",
1443
- )
1444
- else:
1445
- self.logger.info(
1446
- "Partition -> '%s' successfully assigned to license -> '%s' (%s)",
1447
- partition_name,
1448
- self.settings.otawp.product_name,
1449
- "USERS",
1450
- )
1451
1205
  otawp_object = OTAWP(
1452
- self.settings.otawp.protocol,
1453
- self.settings.k8s.sts_otawp,
1454
- str(self.settings.otawp.port),
1455
- "sysadmin",
1456
- self.settings.otawp.password.get_secret_value(),
1457
- "",
1458
- self.settings.otcs.partition,
1459
- self.settings.otds.admin_partition,
1460
- self.settings.k8s.cm_otawp,
1461
- otcs_resource_id,
1462
- self.settings.otds.url,
1463
- self.settings.otcs.url,
1464
- self.settings.otcs.base_path,
1465
- self.settings.otawp.license_file,
1466
- self.settings.otawp.product_name,
1467
- self.settings.otawp.product_description,
1206
+ protocol=self.settings.otawp.protocol,
1207
+ hostname=self.settings.k8s.sts_otawp,
1208
+ port=str(self.settings.otawp.port),
1209
+ username="sysadmin",
1210
+ password=self.settings.otawp.password.get_secret_value(),
1211
+ organization=self.settings.otawp.organization,
1212
+ otawp_ticket="",
1213
+ config_map_name=self.settings.k8s.cm_otawp,
1214
+ license_file=self.settings.otawp.license_file,
1215
+ product_name=self.settings.otawp.product_name,
1216
+ product_description=self.settings.otawp.product_description,
1468
1217
  logger=self.logger,
1469
1218
  )
1219
+
1470
1220
  return otawp_object
1471
1221
 
1472
1222
  # end method definition
@@ -1484,8 +1234,9 @@ class Customizer:
1484
1234
  OTCS object of the backend.
1485
1235
  frontend:
1486
1236
  OTCS object of the frontend.
1487
- extra_wait_time (int):
1237
+ extra_wait_time (int, optional):
1488
1238
  Extra wait time after the restart to make sure pods are responsive again.
1239
+ Default is 60.
1489
1240
 
1490
1241
  Returns:
1491
1242
  None
@@ -1500,6 +1251,18 @@ class Customizer:
1500
1251
 
1501
1252
  self.logger.info("Restart OTCS frontend and backend pods...")
1502
1253
 
1254
+ # Get number of replicas or update it for frontends as it might change with dynamic scaling:
1255
+ otcs_frontend_scale = self.k8s_object.get_stateful_set_scale(
1256
+ sts_name=self.settings.k8s.sts_otcs_frontend,
1257
+ )
1258
+ if not otcs_frontend_scale:
1259
+ self.logger.error(
1260
+ "Cannot find Kubernetes Stateful Set -> '%s' for OTCS Frontends!",
1261
+ self.settings.k8s.sts_otcs_frontend,
1262
+ )
1263
+
1264
+ self.settings.k8s.sts_otcs_frontend_replicas = otcs_frontend_scale.spec.replicas
1265
+
1503
1266
  # Restart all frontends:
1504
1267
  for x in range(self.settings.k8s.sts_otcs_frontend_replicas):
1505
1268
  pod_name = self.settings.k8s.sts_otcs_frontend + "-" + str(x)
@@ -1510,7 +1273,7 @@ class Customizer:
1510
1273
  ["/bin/sh", "-c", "touch /tmp/keepalive"],
1511
1274
  container="otcs-frontend-container",
1512
1275
  )
1513
- self.logger.info("Restarting pod -> '%s'", pod_name)
1276
+ self.logger.info("Restarting OTCS in pod -> '%s'", pod_name)
1514
1277
  self.k8s_object.exec_pod_command(
1515
1278
  pod_name,
1516
1279
  ["/bin/sh", "-c", "/opt/opentext/cs/stop_csserver"],
@@ -1532,7 +1295,7 @@ class Customizer:
1532
1295
  ["/bin/sh", "-c", "touch /tmp/keepalive"],
1533
1296
  container="otcs-admin-container",
1534
1297
  )
1535
- self.logger.info("Restarting pod -> '%s'", pod_name)
1298
+ self.logger.info("Restarting OTCS in pod -> '%s'", pod_name)
1536
1299
  self.k8s_object.exec_pod_command(
1537
1300
  pod_name,
1538
1301
  ["/bin/sh", "-c", "/opt/opentext/cs/stop_csserver"],
@@ -1763,8 +1526,8 @@ class Customizer:
1763
1526
  return False
1764
1527
 
1765
1528
  # Establish in-cluster Kubernetes connection
1766
- self.log_header("Initialize Kubernetes")
1767
1529
  if self.settings.k8s.enabled:
1530
+ self.log_header("Initialize Kubernetes")
1768
1531
  try:
1769
1532
  self.k8s_object = self.init_k8s()
1770
1533
 
@@ -1810,6 +1573,7 @@ class Customizer:
1810
1573
  self.logger.error("Failed to initialize OTAC - exiting...")
1811
1574
  return False
1812
1575
  else:
1576
+ self.logger.info("Archive Center is disabled.")
1813
1577
  self.otac_object = None
1814
1578
 
1815
1579
  if self.settings.otiv.enabled: # is Intelligent Viewing deployed?
@@ -1817,16 +1581,18 @@ class Customizer:
1817
1581
 
1818
1582
  self.otiv_object = self.init_otiv()
1819
1583
  else:
1584
+ self.logger.info("Intelligent Viewing is disabled.")
1820
1585
  self.otiv_object = None
1821
1586
 
1822
1587
  if self.settings.otpd.enabled: # is PowerDocs deployed?
1823
- self.log_header("Initialize OTPD")
1588
+ self.log_header("Initialize PowerDocs")
1824
1589
 
1825
1590
  self.otpd_object = self.init_otpd()
1826
1591
  if not self.otpd_object:
1827
1592
  self.logger.error("Failed to initialize OTPD - exiting...")
1828
1593
  return False
1829
1594
  else:
1595
+ self.logger.info("PowerDocs is disabled.")
1830
1596
  self.otpd_object = None
1831
1597
 
1832
1598
  if self.settings.coreshare.enabled: # is Core Share enabled?
@@ -1837,10 +1603,11 @@ class Customizer:
1837
1603
  self.logger.error("Failed to initialize Core Share - exiting...")
1838
1604
  return False
1839
1605
  else:
1606
+ self.logger.info("Core Share is disabled.")
1840
1607
  self.core_share_object = None
1841
1608
 
1842
1609
  if (
1843
- self.settings.m365.enabled and self.settings.m365.username != "" and self.settings.m365.password != ""
1610
+ self.settings.m365.enabled and self.settings.m365.client_id != "" and self.settings.m365.client_secret != ""
1844
1611
  ): # is M365 enabled?
1845
1612
  self.log_header("Initialize Microsoft 365")
1846
1613
 
@@ -1849,6 +1616,9 @@ class Customizer:
1849
1616
  if not self.m365_object:
1850
1617
  self.logger.error("Failed to initialize Microsoft 365!")
1851
1618
  return False
1619
+ else:
1620
+ self.logger.info("Microsoft 365 is disabled or credentials are missing.")
1621
+ self.m365_object = None
1852
1622
 
1853
1623
  if self.settings.avts.enabled:
1854
1624
  self.log_header("Initialize Aviator Search")
@@ -1857,6 +1627,7 @@ class Customizer:
1857
1627
  self.logger.error("Failed to initialize Aviator Search")
1858
1628
  return False
1859
1629
  else:
1630
+ self.logger.info("Aviator Search is disabled.")
1860
1631
  self.avts_object = None
1861
1632
 
1862
1633
  return True
@@ -1938,6 +1709,7 @@ class Customizer:
1938
1709
  m365_object=self.m365_object,
1939
1710
  core_share_object=self.core_share_object,
1940
1711
  browser_automation_object=self.browser_automation_object,
1712
+ browser_headless=self.settings.headless_browser,
1941
1713
  placeholder_values=self.settings.placeholder_values, # this dict includes placeholder replacements for the Ressource IDs of OTAWP and OTCS
1942
1714
  log_header_callback=self.log_header,
1943
1715
  stop_on_error=self.settings.stop_on_error,
@@ -2031,42 +1803,44 @@ class Customizer:
2031
1803
  if self.settings.otcs.maintenance_mode:
2032
1804
  self.set_maintenance_mode(enable=False)
2033
1805
 
2034
- # Restart AppWorksPlatform pod if it is deployed (to make settings effective):
2035
- if self.settings.otawp.enabled: # is AppWorks Platform deployed?
2036
- otawp_resource = self.otds_object.get_resource(
2037
- name=self.settings.otawp.resource_name,
2038
- )
2039
- if "allowImpersonation" not in otawp_resource or not otawp_resource["allowImpersonation"]:
2040
- # Allow impersonation for all users:
2041
- self.logger.warning(
2042
- "OTAWP impersonation is not correct in OTDS before OTAWP pod restart!",
2043
- )
2044
- else:
2045
- self.logger.info(
2046
- "OTAWP impersonation is correct in OTDS before OTAWP pod restart!",
2047
- )
2048
- self.logger.info("Restart OTAWP pod...")
2049
- self.restart_otawp_pod()
2050
- # For some reason we need to double-check that the impersonation
2051
- # for OTAWP has been set correctly and if not set it again:
2052
- otawp_resource = self.otds_object.get_resource(
2053
- name=self.settings.otawp.resource_name,
2054
- )
2055
- if "allowImpersonation" not in otawp_resource or not otawp_resource["allowImpersonation"]:
2056
- # Allow impersonation for all users:
2057
- self.logger.warning(
2058
- "OTAWP impersonation is not correct in OTDS - set it once more...",
2059
- )
2060
- self.otds_object.impersonate_resource(
2061
- resource_name=self.settings.otawp.resource_name,
2062
- )
2063
-
2064
- # Restart Aviator Search (Omnigroup) to ensure group synchronisation is working
2065
- if self.settings.avts.enabled: # is Aviator Search deployed?
2066
- self.logger.info(
2067
- "Restarting Aviator Search Omnigroup server after creation of OTDS ClientID/ClientSecret...",
2068
- )
2069
- self.k8s_object.restart_stateful_set(sts_name="idol-omnigroupserver")
1806
+ # Code below disbaled -> not needed anymore, will be done via "kubernetes" payload section
1807
+ #
1808
+ # # Restart AppWorksPlatform pod if it is deployed (to make settings effective):
1809
+ # if self.settings.otawp.enabled: # is AppWorks Platform deployed?
1810
+ # otawp_resource = self.otds_object.get_resource(
1811
+ # name=self.settings.otawp.resource_name,
1812
+ # )
1813
+ # if "allowImpersonation" not in otawp_resource or not otawp_resource["allowImpersonation"]:
1814
+ # # Allow impersonation for all users:
1815
+ # self.logger.warning(
1816
+ # "OTAWP impersonation is not correct in OTDS before OTAWP pod restart!",
1817
+ # )
1818
+ # else:
1819
+ # self.logger.info(
1820
+ # "OTAWP impersonation is correct in OTDS before OTAWP pod restart!",
1821
+ # )
1822
+ # self.logger.info("Restart OTAWP pod...")
1823
+ # self.restart_otawp_pod()
1824
+ # # For some reason we need to double-check that the impersonation
1825
+ # # for OTAWP has been set correctly and if not set it again:
1826
+ # otawp_resource = self.otds_object.get_resource(
1827
+ # name=self.settings.otawp.resource_name,
1828
+ # )
1829
+ # if "allowImpersonation" not in otawp_resource or not otawp_resource["allowImpersonation"]:
1830
+ # # Allow impersonation for all users:
1831
+ # self.logger.warning(
1832
+ # "OTAWP impersonation is not correct in OTDS - set it once more...",
1833
+ # )
1834
+ # self.otds_object.impersonate_resource(
1835
+ # resource_name=self.settings.otawp.resource_name,
1836
+ # )
1837
+
1838
+ # # Restart Aviator Search (Omnigroup) to ensure group synchronisation is working
1839
+ # if self.settings.avts.enabled: # is Aviator Search deployed?
1840
+ # self.logger.info(
1841
+ # "Restarting Aviator Search Omnigroup server after creation of OTDS client ID and client secret...",
1842
+ # )
1843
+ # self.k8s_object.restart_stateful_set(sts_name="idol-omnigroupserver")
2070
1844
 
2071
1845
  # Upload log file for later review to "Deployment" folder
2072
1846
  # in "Administration" folder in OTCS Enterprise volume: