opentf-toolkit-nightly 0.62.0.dev1298__py3-none-any.whl → 0.62.0.dev1307__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.
opentf/scripts/startup.py CHANGED
@@ -54,6 +54,7 @@ ENVIRONMENT_VARIABLES = {
54
54
  'DEBUG_LEVEL': 'INFO',
55
55
  'HTTP_PROXY': None,
56
56
  'HTTPS_PROXY': None,
57
+ 'JAVA_TRUSTSTORE': None,
57
58
  'KEY_SIZE': 4096,
58
59
  'NO_PROXY': None,
59
60
  'OPENTF_TELEMETRY': None,
@@ -101,7 +102,7 @@ def _get_env_int(var: str) -> int:
101
102
  except ValueError:
102
103
  val = ENVIRONMENT_VARIABLES[var]
103
104
  logging.warning(
104
- "Environment variable '%s' not an integer, defaulting to %d.",
105
+ 'Environment variable "%s" not an integer, defaulting to %d.',
105
106
  var,
106
107
  val,
107
108
  )
@@ -228,16 +229,16 @@ def parse_and_start(
228
229
  return result
229
230
  for path in paths:
230
231
  for entry in os.walk(path):
231
- logging.debug("Reading path '%s'.", entry[0])
232
+ logging.debug('Reading path "%s".', entry[0])
232
233
  if item not in entry[2]:
233
234
  logging.debug('(No manifest found in path.)')
234
235
  continue
235
- logging.debug("(Found a '%s' manifest, parsing.)", item)
236
+ logging.debug('(Found a "%s" manifest, parsing.)', item)
236
237
  with open(os.path.join(entry[0], item), 'r', encoding='utf-8') as manifests:
237
238
  for manifest in yaml.safe_load_all(manifests):
238
239
  if disabled and manifest['metadata']['name'].lower() in disabled:
239
240
  logging.debug(
240
- "(Plugin '%s' explicitly disabled, ignoring.)",
241
+ '(Plugin "%s" explicitly disabled, ignoring.)',
241
242
  manifest['metadata']['name'],
242
243
  )
243
244
  continue
@@ -308,7 +309,7 @@ def maybe_start_otelcol():
308
309
  logging.error('Failed to start OpenTelemetry Collector: %s.', str(err))
309
310
  elif telemetry:
310
311
  logging.warning(
311
- 'Unexpected OPENTF_TELEMETRY environment variable value %s (accepted values are %s).',
312
+ 'Unexpected OPENTF_TELEMETRY environment variable value "%s" (accepted values are %s).',
312
313
  telemetry,
313
314
  ', '.join(expected),
314
315
  )
@@ -412,7 +413,7 @@ def maybe_generate_token() -> None:
412
413
  if public_key := os.environ.get('PUBLIC_KEY'):
413
414
  if len(public_key.split()) < 2:
414
415
  logging.error(
415
- "PUBLIC_KEY must be of the form: 'type-name base64-encoded-ssh-public-key [optional comment]', got: %s.",
416
+ 'PUBLIC_KEY must be of the form: "type-name base64-encoded-ssh-public-key [optional comment]", got: %s.',
416
417
  public_key,
417
418
  )
418
419
  sys.exit(1)
@@ -436,7 +437,7 @@ def maybe_populate_keystore() -> None:
436
437
  if (ca_bundle := os.environ.get('CURL_CA_BUNDLE')) is None:
437
438
  return
438
439
  if not os.path.isfile(ca_bundle):
439
- logging.error("CURL_CA_BUNDLE '%s' does not exist, aborting.", ca_bundle)
440
+ logging.error('CURL_CA_BUNDLE "%s" does not exist, aborting.', ca_bundle)
440
441
  sys.exit(1)
441
442
 
442
443
  with open(ca_bundle, 'r', encoding='utf-8') as bundle_file:
@@ -444,11 +445,20 @@ def maybe_populate_keystore() -> None:
444
445
  if not ca_list[-1].rstrip():
445
446
  ca_list.pop()
446
447
 
448
+ if truststore := os.environ.get('JAVA_TRUSTSTORE'):
449
+ logging.debug('Using truststore "%s".', truststore)
450
+ keystore = ('-keystore', truststore)
451
+ else:
452
+ logging.debug('Using default truststore.')
453
+ keystore = ('-cacerts',)
454
+
447
455
  for ca_counter, ca in enumerate(ca_list):
448
- add_keystore_certificate(ca_counter, f'{ca}{CA_END}')
456
+ add_keystore_certificate(ca_counter, f'{ca}{CA_END}', keystore)
449
457
 
450
458
 
451
- def add_keystore_certificate(ca_counter: int, ca: str) -> None:
459
+ def add_keystore_certificate(
460
+ ca_counter: int, ca: str, keystore: Tuple[str, ...]
461
+ ) -> None:
452
462
  """Add certificate to keystore.
453
463
 
454
464
  !!! warning
@@ -469,7 +479,7 @@ def add_keystore_certificate(ca_counter: int, ca: str) -> None:
469
479
  ca_alias = f'opentf:{ca_counter}_{os.path.basename(ca_path)}'
470
480
  try:
471
481
  ca_file.write(ca)
472
- logging.debug("File '%s' written.", ca_path)
482
+ logging.debug('File "%s" written.', ca_path)
473
483
  except IOError as err:
474
484
  logging.error('An error occurred while writing the file: %s.', err)
475
485
  sys.exit(1)
@@ -483,10 +493,10 @@ def add_keystore_certificate(ca_counter: int, ca: str) -> None:
483
493
  ca_alias,
484
494
  '-file',
485
495
  ca_path,
486
- '-cacerts',
487
496
  '-storepass',
488
497
  'changeit',
489
498
  '-noprompt',
499
+ *keystore,
490
500
  ],
491
501
  stdout=subprocess.PIPE,
492
502
  stderr=subprocess.STDOUT,
@@ -514,14 +524,14 @@ def _ensure_abac_if_defined(name, value):
514
524
  if not OPENTF_AUTHORIZATION_MODE:
515
525
  logging.error(
516
526
  '{0} is defined but OPENTF_AUTHORIZATION_MODE is undefined.'
517
- " OPENTF_AUTHORIZATION_MODE must include 'ABAC' to use {0}.".format(
527
+ ' OPENTF_AUTHORIZATION_MODE must include "ABAC" to use {0}.'.format(
518
528
  name
519
529
  )
520
530
  )
521
531
  sys.exit(1)
522
532
  if 'ABAC' not in OPENTF_AUTHORIZATION_MODE.split(','):
523
533
  logging.error(
524
- "OPENTF_AUTHORIZATION_MODE must include 'ABAC' to use %s.", name
534
+ 'OPENTF_AUTHORIZATION_MODE must include "ABAC" to use %s.', name
525
535
  )
526
536
  sys.exit(1)
527
537
  if not os.path.isfile(value):
@@ -89,7 +89,7 @@ def _normalize_inputs(inputs: Dict[str, Any]) -> None:
89
89
  normalized = key.replace('_', '-')
90
90
  if normalized in inputs:
91
91
  raise core.ExecutionError(
92
- f"Both '{key}' and '{normalized}' specified in inputs."
92
+ f'Both "{key}" and "{normalized}" specified in inputs.'
93
93
  )
94
94
  inputs[normalized] = inputs.pop(key)
95
95
 
@@ -127,7 +127,10 @@ def _ensure_inputs_match(
127
127
  """Check inputs.
128
128
 
129
129
  Normalize inputs, fills missing optional inputs with their default
130
- values if specified.
130
+ values.
131
+
132
+ If one of the inputs is a template (name starting with '{'), no
133
+ normalization is performed.
131
134
 
132
135
  # Raised exceptions
133
136
 
@@ -140,25 +143,34 @@ def _ensure_inputs_match(
140
143
 
141
144
  declaration, additional_inputs = entry
142
145
  for key in declaration:
143
- if key.startswith('{'):
146
+ if key.startswith('{'): # Skip template entries
144
147
  break
145
148
  else:
146
149
  _normalize_inputs(inputs)
147
150
  for key, definition in declaration.items():
151
+ if key.startswith('{'):
152
+ continue
148
153
  if key not in inputs:
149
- if definition.get('required'):
150
- raise core.ExecutionError(f"Mandatory input '{key}' not provided.")
154
+ if definition.get('required', False):
155
+ raise core.ExecutionError(f'Mandatory input "{key}" not provided.')
151
156
  if (default := definition.get('default')) is not None:
152
157
  inputs[key] = default
158
+ elif type_ := definition.get('type'):
159
+ if type_ == 'string':
160
+ inputs[key] = ''
161
+ elif type_ == 'number':
162
+ inputs[key] = 0
163
+ elif type_ == 'boolean':
164
+ inputs[key] = False
153
165
 
154
166
  if additional_inputs:
155
167
  return
156
168
 
157
169
  for key in inputs:
158
170
  if key not in declaration and key.replace('_', '-') not in declaration:
159
- allowed = ', '.join(sorted([f"'{k}'" for k in declaration.keys()]))
171
+ allowed = ', '.join(sorted([f'"{k}"' for k in declaration.keys()]))
160
172
  raise core.ExecutionError(
161
- f"Unexpected input '{key}' found in function step. Allowed inputs: {allowed}."
173
+ f'Unexpected input "{key}" found in function step. Allowed inputs: {allowed}.'
162
174
  )
163
175
 
164
176
 
@@ -256,15 +268,15 @@ def _read_hooks_definition(
256
268
  hooks = yaml.safe_load(src)
257
269
  if not isinstance(hooks, dict) or not 'hooks' in hooks:
258
270
  plugin.logger.error(
259
- "Hooks definition file '%s' needs a 'hooks' entry, ignoring.", hooksfile
271
+ 'Hooks definition file "%s" needs a "hooks" entry, ignoring.', hooksfile
260
272
  )
261
273
  config['hooks'] = [invalid]
262
274
  return
263
275
 
264
276
  if config.get('hooks'):
265
- plugin.logger.info("Replacing hooks definition using '%s'.", hooksfile)
277
+ plugin.logger.info('Replacing hooks definition using "%s".', hooksfile)
266
278
  else:
267
- plugin.logger.info("Reading hooks definition from '%s'.", hooksfile)
279
+ plugin.logger.info('Reading hooks definition from "%s".', hooksfile)
268
280
 
269
281
  config['hooks'] = hooks['hooks']
270
282
  valid, extra = validate_schema(schema, config)
@@ -272,11 +284,11 @@ def _read_hooks_definition(
272
284
  return
273
285
 
274
286
  plugin.logger.error(
275
- "Error while verifying '%s' hooks definition: %s.", hooksfile, extra
287
+ 'Error while verifying "%s" hooks definition: %s.', hooksfile, extra
276
288
  )
277
289
  except Exception as err:
278
290
  plugin.logger.error(
279
- "Error while reading '%s' hooks definition: %s.", hooksfile, err
291
+ 'Error while reading "%s" hooks definition: %s.', hooksfile, err
280
292
  )
281
293
 
282
294
  config['hooks'] = [invalid]
@@ -351,7 +363,7 @@ def _run_handlers(plugin: Flask, file, handlers) -> None:
351
363
  handler(plugin, file, *args, **kwargs)
352
364
  except Exception as err:
353
365
  plugin.logger.error(
354
- "Handler '%s' for file '%s' failed: %s. Ignoring.", handler, file, err
366
+ 'Handler "%s" for file "%s" failed: %s. Ignoring.', handler, file, err
355
367
  )
356
368
 
357
369
 
@@ -421,7 +433,7 @@ def watch_file(plugin: Flask, path: str, handler, *args, **kwargs) -> None:
421
433
  if need_init:
422
434
  plugin.config[WATCHEDFILES_KEY] = defaultdict(list)
423
435
  plugin.config[WATCHEDFILES_EVENT_KEY] = threading.Event()
424
- plugin.logger.debug("Adding configuration watcher for '%s'.", path)
436
+ plugin.logger.debug('Adding configuration watcher for "%s".', path)
425
437
  plugin.config[WATCHEDFILES_KEY][path].append((handler, args, kwargs))
426
438
  if need_init:
427
439
  _start_watchdog(plugin)
@@ -503,14 +515,14 @@ def _subscribe(
503
515
  }
504
516
  except KeyError as err:
505
517
  plugin.logger.error(
506
- "Invalid descriptor 'outputs' section, could not find key %s in: %s.",
518
+ 'Invalid descriptor "outputs" section, could not find key %s in: %s.',
507
519
  err,
508
520
  manifest.get('outputs', {}),
509
521
  )
510
522
  sys.exit(2)
511
523
  except Exception as err:
512
524
  plugin.logger.error(
513
- "Invalid descriptor 'outputs' section, got %s while parsing outputs.", err
525
+ 'Invalid descriptor "outputs" section, got %s while parsing outputs.', err
514
526
  )
515
527
  sys.exit(2)
516
528
  return subscribe(kind=kind, target='inbox', app=plugin, labels=labels)
@@ -546,7 +558,7 @@ def run_plugin(plugin: Flask) -> None:
546
558
  )
547
559
  else:
548
560
  plugin.logger.warning(
549
- "At least one of 'category', 'categoryPrefix' required, ignoring."
561
+ 'At least one of "category", "categoryPrefix" required, ignoring.'
550
562
  )
551
563
  elif context[KIND_KEY] == EXECUTIONCOMMAND:
552
564
  context[SUBSCRIPTION_KEY].append(
@@ -663,15 +675,15 @@ def make_plugin(
663
675
 
664
676
  if not _one_and_only_one(channel, generator, provider, providers, publisher):
665
677
  raise ValueError(
666
- "One and only one of 'channel', 'generator', 'provider', 'providers', or 'publisher' is required."
678
+ 'One and only one of "channel", "generator", "provider", "providers", or "publisher" is required.'
667
679
  )
668
680
  if not (descriptor is None or isinstance(descriptor, (dict, list))):
669
681
  raise ValueError(
670
- "'descriptor', if specified, must be a dictionary or a list of dictionaries."
682
+ '"descriptor", if specified, must be a dictionary or a list of dictionaries.'
671
683
  )
672
684
  if channel and (not isinstance(args, list) or len(args) != 1):
673
685
  raise ValueError(
674
- "'args' is required for channel plugins and must be a list of one element."
686
+ '"args" is required for channel plugins and must be a list of one element.'
675
687
  )
676
688
 
677
689
  kind = (
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: opentf-toolkit-nightly
3
- Version: 0.62.0.dev1298
3
+ Version: 0.62.0.dev1307
4
4
  Summary: OpenTestFactory Orchestrator Toolkit
5
5
  Home-page: https://gitlab.com/henixdevelopment/open-source/opentestfactory/python-toolkit
6
6
  Author: Martin Lafaix
@@ -54,12 +54,12 @@ opentf/schemas/opentestfactory.org/v1beta1/ServiceConfig.json,sha256=m5ZgWAKbutu
54
54
  opentf/schemas/opentestfactory.org/v1beta1/Workflow.json,sha256=QZ8mM9PhzsI9gTmwmKTWYNoRn--rtcM3L0PzgnPBfMU,15424
55
55
  opentf/schemas/opentestfactory.org/v1beta2/ServiceConfig.json,sha256=rEvK2YWL5lG94_qYgR_GnLWNsaQhaQ-2kuZdWJr5NnY,3517
56
56
  opentf/scripts/launch_java_service.sh,sha256=S0jAaCuv2sZy0Gf2NGBuPX-eD531rcM-b0fNyhmzSjw,2423
57
- opentf/scripts/startup.py,sha256=vOGxl7xBcp1-_LsAKiOmeOqFl2iT81A2XRrXBLUrNi4,22785
58
- opentf/toolkit/__init__.py,sha256=ohrde5mcMY26p64E0Z2XunZAWYOiEkXKTg5E1J4TGGc,23571
57
+ opentf/scripts/startup.py,sha256=AcVXU2auPvqMb_6OpGzkVqrpgYV6vz7x_Rnv8YbAEkk,23114
58
+ opentf/toolkit/__init__.py,sha256=dkNESdDAOcP_3v_NHFPo61P-wOZ8hA1PTkzKkm-7I2k,24026
59
59
  opentf/toolkit/channels.py,sha256=6qKSsAgq_oJpuDRiKqVUz-EAjdfikcCG3SFAGmKZdhQ,25551
60
60
  opentf/toolkit/core.py,sha256=fqnGgaYnuVcd4fyeNIwpc0QtyUo7jsKeVgdkBfY3iqo,9443
61
- opentf_toolkit_nightly-0.62.0.dev1298.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
62
- opentf_toolkit_nightly-0.62.0.dev1298.dist-info/METADATA,sha256=zPOTouTQoLWUCjDEAvzyd6zBD72RgfGlTL9UGDTITuw,2192
63
- opentf_toolkit_nightly-0.62.0.dev1298.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
64
- opentf_toolkit_nightly-0.62.0.dev1298.dist-info/top_level.txt,sha256=_gPuE6GTT6UNXy1DjtmQSfCcZb_qYA2vWmjg7a30AGk,7
65
- opentf_toolkit_nightly-0.62.0.dev1298.dist-info/RECORD,,
61
+ opentf_toolkit_nightly-0.62.0.dev1307.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
62
+ opentf_toolkit_nightly-0.62.0.dev1307.dist-info/METADATA,sha256=YuaUPxmh-meImk1D1mcqCmpNn0jzE00xVLcJ-kQuUD8,2192
63
+ opentf_toolkit_nightly-0.62.0.dev1307.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
64
+ opentf_toolkit_nightly-0.62.0.dev1307.dist-info/top_level.txt,sha256=_gPuE6GTT6UNXy1DjtmQSfCcZb_qYA2vWmjg7a30AGk,7
65
+ opentf_toolkit_nightly-0.62.0.dev1307.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.2)
2
+ Generator: setuptools (76.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5