Skip to content

Commit 9e5dd7f

Browse files
authored
[ContainerRegistry] Add 'acrcssc' extension for public preview (#8530)
1 parent 45a031d commit 9e5dd7f

37 files changed

+8970
-0
lines changed

src/acrcssc/HISTORY.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
.. :changelog:
2+
3+
Release History
4+
===============
5+
6+
1.0.0b1
7+
++++++
8+
* Release for Public Preview
9+
* Added `list`and `cancel-run` commands for workflows
10+
* `list` command provide output on the scan and patch status of the registry
11+
* `cancel-run` command allows to canceling all running scan and patch tasks
12+
13+
14+
0.1.0b1
15+
++++++
16+
* Initial release for Private Preview

src/acrcssc/README.rst

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
Microsoft Azure CLI 'acrcssc' Extension
2+
==========================================
3+
4+
Azure Container Registry - Container Secure Supply Chain (Continuous Patching)
5+
==========================================
6+
7+
Overview
8+
========
9+
The `acrcssc` extension for Azure CLI provides continuous patching capabilities for Azure Container Registry (ACR). This extension helps automate the process of scanning and patching container images to ensure they are up-to-date with the latest security patches. Scans your configured list of images for vulnerabilities (CVEs) using Trivy and patch them using Copacetic.
10+
11+
Preview Limitations
12+
===================
13+
Continuous Patching is currently in preview. The following limitations apply:
14+
15+
- Windows-based container images aren’t supported
16+
- Only "OS-level" vulnerabilities will be patched. This includes packages in the image managed by a package manager such as “apt” and “yum”. Vulnerabilities at the “application level” are unable to be patched, such as compiled languages like Go, Python, NodeJS
17+
- Patching is only supported in Public regions, not in Sovereign regions
18+
- CSSC patching is not supported for registries or in regions where Tasks are unavailable.
19+
20+
Features
21+
========
22+
- **Continuous Patching Workflow**: Automates the process of scanning and patching container images.
23+
- **Task Management**: Create, update, delete, show, and cancel continuous patch tasks in the registry.
24+
- **Dry Run Mode**: Validate the configuration without making any changes.
25+
- **Immediate Run**: Trigger the patching workflow immediately.
26+
- **Run Status**: Monitor the status of the scanning and patching tasks.
27+
28+
Commands
29+
========
30+
- `az acr supply-chain workflow create`: Create a continuous patch task in the registry.
31+
- `az acr supply-chain workflow update`: Update an existing continuous patch task.
32+
- `az acr supply-chain workflow delete`: Delete a continuous patch task.
33+
- `az acr supply-chain workflow list`: List all continuous patch tasks in the registry.
34+
- `az acr supply-chain workflow show`: Show details of a specific continuous patch task.
35+
- `az acr supply-chain workflow cancel-run`: Cancel all running scan and patch tasks.
36+
37+
Usage
38+
=====
39+
1. **Create a Continuous Patch Task**:
40+
```sh
41+
az acr supply-chain workflow create --resource-group <resource-group> --registry <registry-name> --type continuouspatchv1 --schedule <schedule> --config <config-file>
42+
```
43+
44+
1. **Update a Continuous Patch Task**:
45+
```sh
46+
az acr supply-chain workflow update --resource-group <resource-group> --registry <registry-name> --type continuouspatchv1 --schedule <schedule> --config <config-file>
47+
```
48+
49+
1. **Update with dryrun to test configuration changes**:
50+
```sh
51+
az acr supply-chain workflow update --resource-group <resource-group> --registry <registry-name> --type continuouspatchv1 --config <config-file> --dryrun
52+
```
53+
54+
1. **Delete a Continuous Patch Task**:
55+
```sh
56+
az acr supply-chain workflow delete --resource-group <resource-group> --registry <registry-name> --type continuouspatchv1
57+
```
58+
59+
1. **List Continuous Patch Tasks**:
60+
```sh
61+
az acr supply-chain workflow list --resource-group <resource-group> --registry <registry-name> --type continuouspatchv1 --run-status <status>
62+
```
63+
64+
1. **Show a Continuous Patch Task**:
65+
```sh
66+
az acr supply-chain workflow show --resource-group <resource-group> --registry <registry-name> --type continuouspatchv1
67+
```
68+
69+
1. **Cancel all Scan and Patch Running Tasks**:
70+
```sh
71+
az acr supply-chain workflow cancel-run --resource-group <resource-group> --registry <registry-name> --type continuouspatchv1
72+
```
73+
74+
Configuration
75+
=============
76+
The configuration file for the continuous patch task should define the repositories to be scanned and patched, the schedule for the task, and any other relevant settings.
77+
78+
Example Configuration:
79+
80+
```JSON
81+
{
82+
"repositories": [
83+
{
84+
"repository": "alpine",
85+
"tags": ["tag1", "tag2"],
86+
"enabled": true
87+
},
88+
{
89+
"repository": "python",
90+
"tags": ["*"],
91+
"enabled": false
92+
}
93+
],
94+
"version": "v1",
95+
"tag-convention": "floating"
96+
}
97+
```
98+
99+
Tag Convention
100+
==============
101+
The `tag-convention` property in the configuration file determines how the tags for patched images are managed. It can have the following values:
102+
103+
- **incremental**: This is the default behavior. It increases the patch version of the tag. For example, if the original tag is `1.0`, the patched tags will be `1.0-1`, `1.0-2`, etc.
104+
- **floating**: This reuses the tag postfix `patched` for patching. For example, if the original tag is `1.0`, the patched tag will be `1.0-patched`.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# --------------------------------------------------------------------------------------------
2+
# Copyright (c) Microsoft Corporation. All rights reserved.
3+
# Licensed under the MIT License. See License.txt in the project root for license information.
4+
# --------------------------------------------------------------------------------------------
5+
6+
from azure.cli.core import AzCommandsLoader
7+
8+
from azext_acrcssc._help import helps # pylint: disable=unused-import
9+
10+
11+
class AcrcsscCommandsLoader(AzCommandsLoader):
12+
13+
def __init__(self, cli_ctx=None):
14+
from azure.cli.core.commands import CliCommandType
15+
from azext_acrcssc._client_factory import cf_acr
16+
acrcssc_custom = CliCommandType(
17+
operations_tmpl='azext_acrcssc.custom#{}',
18+
client_factory=cf_acr)
19+
super(AcrcsscCommandsLoader, self).__init__(cli_ctx=cli_ctx,
20+
custom_command_type=acrcssc_custom)
21+
22+
def load_command_table(self, args):
23+
from azext_acrcssc.commands import load_command_table
24+
load_command_table(self, args)
25+
return self.command_table
26+
27+
def load_arguments(self, command):
28+
from azext_acrcssc._params import load_arguments
29+
load_arguments(self, command)
30+
31+
32+
COMMAND_LOADER_CLS = AcrcsscCommandsLoader
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# --------------------------------------------------------------------------------------------
2+
# Copyright (c) Microsoft Corporation. All rights reserved.
3+
# Licensed under the MIT License. See License.txt in the project root for license information.
4+
# --------------------------------------------------------------------------------------------
5+
from azure.cli.core.commands.client_factory import get_mgmt_service_client
6+
from azure.cli.core.profiles import ResourceType
7+
from azure.mgmt.containerregistry import ContainerRegistryManagementClient
8+
from .helper._constants import (
9+
ACR_API_VERSION_2023_01_01_PREVIEW,
10+
ACR_API_VERSION_2019_06_01_PREVIEW
11+
)
12+
13+
from azure.mgmt.authorization import AuthorizationManagementClient
14+
15+
16+
def cf_acr(cli_ctx, *_) -> ContainerRegistryManagementClient:
17+
return get_mgmt_service_client(cli_ctx,
18+
ResourceType.MGMT_CONTAINERREGISTRY,
19+
api_version=ACR_API_VERSION_2023_01_01_PREVIEW)
20+
21+
22+
def cf_acr_registries(cli_ctx, *_) -> ContainerRegistryManagementClient:
23+
return get_mgmt_service_client(cli_ctx,
24+
ResourceType.MGMT_CONTAINERREGISTRY,
25+
api_version=ACR_API_VERSION_2023_01_01_PREVIEW).registries
26+
27+
28+
def cf_acr_tasks(cli_ctx, *_):
29+
return get_mgmt_service_client(cli_ctx,
30+
ResourceType.MGMT_CONTAINERREGISTRY,
31+
api_version=ACR_API_VERSION_2019_06_01_PREVIEW).tasks
32+
33+
34+
def cf_acr_registries_tasks(cli_ctx, *_):
35+
return get_mgmt_service_client(cli_ctx,
36+
ResourceType.MGMT_CONTAINERREGISTRY,
37+
api_version=ACR_API_VERSION_2019_06_01_PREVIEW).registries
38+
39+
40+
def cf_acr_taskruns(cli_ctx, *_):
41+
return get_mgmt_service_client(cli_ctx,
42+
ResourceType.MGMT_CONTAINERREGISTRY,
43+
api_version=ACR_API_VERSION_2019_06_01_PREVIEW).task_runs
44+
45+
46+
def cf_acr_runs(cli_ctx, *_):
47+
return get_mgmt_service_client(cli_ctx,
48+
ResourceType.MGMT_CONTAINERREGISTRY,
49+
api_version=ACR_API_VERSION_2019_06_01_PREVIEW).runs
50+
51+
52+
def cf_resources(cli_ctx, subscription_id=None):
53+
return get_mgmt_service_client(cli_ctx,
54+
ResourceType.MGMT_RESOURCE_RESOURCES,
55+
subscription_id=subscription_id)
56+
57+
58+
def cf_authorization(cli_ctx, subscription_id=None) -> AuthorizationManagementClient:
59+
return get_mgmt_service_client(cli_ctx,
60+
ResourceType.MGMT_AUTHORIZATION,
61+
subscription_id=subscription_id, api_version="2022-04-01")

src/acrcssc/azext_acrcssc/_help.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# coding=utf-8
2+
# --------------------------------------------------------------------------------------------
3+
# Copyright (c) Microsoft Corporation. All rights reserved.
4+
# Licensed under the MIT License. See License.txt in the project root for license information.
5+
# --------------------------------------------------------------------------------------------
6+
7+
from knack.help_files import helps # pylint: disable=unused-import
8+
9+
helps['acr supply-chain'] = """
10+
type: group
11+
short-summary: Commands to manage acr supply chain resources.
12+
"""
13+
14+
helps['acr supply-chain workflow'] = """
15+
type: group
16+
short-summary: Commands to manage acr supply chain workflows.
17+
"""
18+
19+
helps['acr supply-chain workflow create'] = """
20+
type: command
21+
short-summary: Create acr supply chain workflow.
22+
examples:
23+
- name: Create acr supply chain workflow
24+
text: az acr supply-chain workflow create -r $MyRegistry -g $MyResourceGroup \
25+
--type continuouspatchv1 --schedule 1d --config path-to-config-file
26+
"""
27+
helps['acr supply-chain workflow update'] = """
28+
type: command
29+
short-summary: Update acr supply chain workflow.
30+
examples:
31+
- name: Update acr supply chain workflow
32+
text: az acr supply-chain workflow update -r $MyRegistry -g $MyResourceGroup --type \
33+
continuouspatchv1 --schedule 1d --config path-to-config-file
34+
"""
35+
36+
helps['acr supply-chain workflow show'] = """
37+
type: command
38+
short-summary: Show acr supply chain workflow tasks.
39+
examples:
40+
- name: Show all acr supply chain workflow
41+
text: az acr supply-chain workflow show -r $MyRegistry -g $MyResourceGroup --type continuouspatchv1
42+
"""
43+
44+
helps['acr supply-chain workflow delete'] = """
45+
type: command
46+
short-summary: Delete acr supply chain workflow.
47+
examples:
48+
- name: Delete acr supply chain workflow and associated configuration files
49+
text: az acr supply-chain workflow delete -r $MyRegistry -g $MyResourceGroup --type continuouspatchv1
50+
"""
51+
52+
helps['acr supply-chain workflow cancel-run'] = """
53+
type: command
54+
short-summary: Cancel currently running supply chain workflow.
55+
examples:
56+
- name: Cancel currently running acr supply chain workflow scans/patch
57+
text: az acr supply-chain workflow cancel-run -r $MyRegistry -g $MyResourceGroup --type continuouspatchv1
58+
"""
59+
60+
helps['acr supply-chain workflow list'] = """
61+
type: command
62+
short-summary: List status of acr supply chain workflow images.
63+
examples:
64+
- name: List all acr supply chain workflow images based on the status provided
65+
text: az acr supply-chain workflow list -r $MyRegistry -g $MyResourceGroup --type continuouspatchv1 --run-status Failed
66+
"""
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# --------------------------------------------------------------------------------------------
2+
# Copyright (c) Microsoft Corporation. All rights reserved.
3+
# Licensed under the MIT License. See License.txt in the project root for license information.
4+
# --------------------------------------------------------------------------------------------
5+
# pylint: disable=line-too-long
6+
from azure.cli.command_modules.acr._constants import REGISTRY_RESOURCE_TYPE
7+
from azure.cli.command_modules.acr._validators import validate_registry_name
8+
from azure.cli.core import AzCommandsLoader
9+
from azure.cli.core.commands.parameters import (
10+
get_resource_name_completion_list,
11+
get_three_state_flag, get_enum_type,
12+
resource_group_name_type
13+
)
14+
from .helper._constants import CONTINUOUSPATCH_SCHEDULE_MAX_DAYS
15+
16+
17+
def load_arguments(self: AzCommandsLoader, _):
18+
from .helper._constants import CSSCTaskTypes
19+
from .helper._workflow_status import WorkflowTaskState
20+
21+
with self.argument_context("acr supply-chain workflow") as c:
22+
c.argument('resource_group', arg_type=resource_group_name_type, completer=get_resource_name_completion_list(REGISTRY_RESOURCE_TYPE))
23+
c.argument('registry_name', options_list=['--registry', '-r'], help='The name of the container registry. It should be specified in lower case. You can configure the default registry name using `az configure --defaults acr=<registry name>`', completer=get_resource_name_completion_list(REGISTRY_RESOURCE_TYPE), configured_default='acr', validator=validate_registry_name)
24+
c.argument("workflow_type", arg_type=get_enum_type(CSSCTaskTypes), options_list=['--type', '-t'], help="Type of workflow task.", required=True)
25+
26+
with self.argument_context("acr supply-chain workflow create") as c:
27+
c.argument("config", help="Configuration file path containing the json schema for the list of repositories and tags to filter within the registry. Schema example:{\"repositories\":[{\"repository\":\"alpine\",\"tags\":[\"tag1\",\"tag2\"],\"enabled\":true},{\"repository\":\"python\",\"tags\":[\"*\"],\"enabled\":false}], \"version\": \"v1\", \"tag-convention\": \"floating\"}. \"tag-convention\" is an optional property, values can be \"incremental\" (the default behavior, will increase the patch version of the tag, for example \"{repository}:{original-tag}-1\", \"{repository}:{original-tag}-2\", etc), or \"floating\" (will reuse the tag \"{repository}:{original-tag}-patched\" for patching)", required=True)
28+
c.argument("schedule", help=f"schedule to run the scan and patching task. E.g. `<n>d` where <n> is the number of days between each run. Max value is {CONTINUOUSPATCH_SCHEDULE_MAX_DAYS}d.", required=True)
29+
c.argument("run_immediately", help="Set this flag to trigger the immediate run of the selected workflow task. Default value: false.", arg_type=get_three_state_flag())
30+
c.argument("dryrun", options_list=["--dry-run"], help="Use this flag to see the qualifying repositories and tags that would be affected by the workflow. Default value: false. 'config' parameter is mandatory to provide with dry-run", arg_type=get_three_state_flag())
31+
32+
with self.argument_context("acr supply-chain workflow update") as c:
33+
c.argument("config", help="Configuration file path containing the json schema for the list of repositories and tags to filter within the registry. Schema example:{\"repositories\":[{\"repository\":\"alpine\",\"tags\":[\"tag1\",\"tag2\"],\"enabled\":true},{\"repository\":\"python\",\"tags\":[\"*\"],\"enabled\":false}], \"version\": \"v1\", \"tag-convention\": \"floating\"}. \"tag-convention\" is an optional property, values can be \"incremental\" (the default behavior, will increase the patch version of the tag, for example \"{repository}:{original-tag}-1\", \"{repository}:{original-tag}-2\", etc), or \"floating\" (will reuse the tag \"{repository}:{original-tag}-patched\" for patching)")
34+
c.argument("schedule", help=f"schedule to run the scan and patching task. E.g. `<n>d` where n is the number of days between each run. Max value is {CONTINUOUSPATCH_SCHEDULE_MAX_DAYS}d.")
35+
c.argument("run_immediately", help="Set this flag to trigger the immediate run of the selected workflow task. Default value: false.", arg_type=get_three_state_flag())
36+
c.argument("dryrun", options_list=["--dry-run"], help="Use this flag to see the qualifying repositories and tags that would be affected by the workflow. Default value: false. 'config' parameter is mandatory to provide with dry-run", arg_type=get_three_state_flag())
37+
38+
with self.argument_context("acr supply-chain workflow list") as c:
39+
c.argument("status", arg_type=get_enum_type(WorkflowTaskState), options_list=["--run-status"], help="Status to filter the supply-chain workflow image status.")
40+
41+
with self.argument_context("acr supply-chain workflow delete") as c:
42+
c.argument("yes", options_list=["--yes", "-y"], help="Proceed with the deletion without user confirmation")

0 commit comments

Comments
 (0)