|
5 | 5 |
|
6 | 6 | import os |
7 | 7 | import sys |
8 | | -from typing import Optional |
| 8 | +from typing import Optional, BinaryIO |
9 | 9 |
|
10 | 10 | from azext_confcom import oras_proxy, os_util, security_policy |
11 | 11 | from azext_confcom._validators import resolve_stdio |
|
22 | 22 | get_image_name, inject_policy_into_template, inject_policy_into_yaml, |
23 | 23 | pretty_print_func, print_existing_policy_from_arm_template, |
24 | 24 | print_existing_policy_from_yaml, print_func, str_to_sha256) |
| 25 | +from azext_confcom.command.fragment_attach import fragment_attach as _fragment_attach |
| 26 | +from azext_confcom.command.fragment_push import fragment_push as _fragment_push |
25 | 27 | from knack.log import get_logger |
26 | 28 | from pkg_resources import parse_version |
27 | 29 |
|
@@ -255,6 +257,7 @@ def acifragmentgen_confcom( |
255 | 257 | upload_fragment: bool = False, |
256 | 258 | no_print: bool = False, |
257 | 259 | fragments_json: str = "", |
| 260 | + out_signed_fragment: bool = False, |
258 | 261 | ): |
259 | 262 | if container_definitions is None: |
260 | 263 | container_definitions = [] |
@@ -361,24 +364,39 @@ def acifragmentgen_confcom( |
361 | 364 |
|
362 | 365 | fragment_text = policy.generate_fragment(namespace, svn, output_type, omit_id=omit_id) |
363 | 366 |
|
364 | | - if output_type != security_policy.OutputType.DEFAULT and not no_print: |
| 367 | + if output_type != security_policy.OutputType.DEFAULT and not no_print and not out_signed_fragment: |
365 | 368 | print(fragment_text) |
366 | 369 |
|
367 | 370 | # take ".rego" off the end of the filename if it's there, it'll get added back later |
368 | 371 | output_filename = output_filename.replace(".rego", "") |
369 | 372 | filename = f"{output_filename or namespace}.rego" |
| 373 | + |
| 374 | + if out_signed_fragment: |
| 375 | + filename = os.path.join("/tmp", filename) |
| 376 | + |
370 | 377 | os_util.write_str_to_file(filename, fragment_text) |
371 | 378 |
|
372 | 379 | if key: |
373 | 380 | cose_proxy = CoseSignToolProxy() |
374 | 381 | iss = cose_proxy.create_issuer(chain) |
375 | 382 | out_path = filename + ".cose" |
376 | 383 |
|
| 384 | + if out_signed_fragment: |
| 385 | + out_path = os.path.join("/tmp", os.path.basename(out_path)) |
| 386 | + |
377 | 387 | cose_proxy.cose_sign(filename, key, chain, feed, iss, algo, out_path) |
378 | | - if upload_fragment and image_target: |
379 | | - oras_proxy.attach_fragment_to_image(image_target, out_path) |
380 | | - elif upload_fragment: |
381 | | - oras_proxy.push_fragment_to_registry(feed, out_path) |
| 388 | + |
| 389 | + # Preserve default behaviour established since version 1.1.0 of attaching |
| 390 | + # the fragment to the first image specified in input |
| 391 | + # (or --image-target if specified) |
| 392 | + if upload_fragment: |
| 393 | + oras_proxy.attach_fragment_to_image( |
| 394 | + image_name=image_target or policy_images[0].containerImage, |
| 395 | + filename=out_path, |
| 396 | + ) |
| 397 | + |
| 398 | + if out_signed_fragment: |
| 399 | + sys.stdout.buffer.write(open(out_path, "rb").read()) |
382 | 400 |
|
383 | 401 |
|
384 | 402 | def katapolicygen_confcom( |
@@ -512,3 +530,23 @@ def get_fragment_output_type(outraw): |
512 | 530 | if outraw: |
513 | 531 | output_type = security_policy.OutputType.RAW |
514 | 532 | return output_type |
| 533 | + |
| 534 | + |
| 535 | +def fragment_attach( |
| 536 | + signed_fragment: BinaryIO, |
| 537 | + manifest_tag: str, |
| 538 | +) -> None: |
| 539 | + _fragment_attach( |
| 540 | + signed_fragment=signed_fragment, |
| 541 | + manifest_tag=manifest_tag |
| 542 | + ) |
| 543 | + |
| 544 | + |
| 545 | +def fragment_push( |
| 546 | + signed_fragment: BinaryIO, |
| 547 | + manifest_tag: str, |
| 548 | +) -> None: |
| 549 | + _fragment_push( |
| 550 | + signed_fragment=signed_fragment, |
| 551 | + manifest_tag=manifest_tag |
| 552 | + ) |
0 commit comments