Skip to content

Commit 6bcc1a6

Browse files
author
Mikolaj Umanski
committed
feat: add custom ca certificates to GA CLI
1 parent 51b8804 commit 6bcc1a6

File tree

11 files changed

+1107
-3
lines changed

11 files changed

+1107
-3
lines changed

src/azure-cli/azure/cli/command_modules/acs/_consts.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,22 @@
206206
CONST_PRIVATE_DNS_ZONE_CONTRIBUTOR_ROLE = "Private DNS Zone Contributor"
207207
CONST_DNS_ZONE_CONTRIBUTOR_ROLE = "DNS Zone Contributor"
208208

209+
CONST_CUSTOM_CA_TEST_CERT = '-----BEGIN CERTIFICATE-----\n' \
210+
'MIICljCCAX4CCQC9zUAgqqqrWzANBgkqhkiG9w0BAQsFADANMQswCQYDVQQGEwJQ\n' \
211+
'TDAeFw0yMjA5MTQwNjIzMjdaFw0yMjA5MTUwNjIzMjdaMA0xCzAJBgNVBAYTAlBM\n' \
212+
'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAopKNIIbvvcPCw9fc4KLX\n' \
213+
'KDtRZobp5L+/1hCN+3OGhk5NvSTpSUrFifxqc0o3IF7YkO3K1n2jAvCMXO16Bf9b\n' \
214+
'OAR7VkCrwGFVkXNjM4wvXAX8CNNvjqd1zDPXSKdE7Wd8k3fTzx6nGUM0UgljIPhH\n' \
215+
'yh4a4Zujd5Ig2P/ZSX0pGJm47JTtMu7MDFHVM5wRWcCrN/H0TCYPIvEOs0B8AZxc\n' \
216+
'p3TF7A6veT5U9pVhQ3Xl9JN6LvvLqPxG3ea10rdv9DYzaiXmSY3ujI3Ri1Q11uWC\n' \
217+
'dtrFIpFu5cHW2OBW+jBXxL0v8xQmkxTLik4BR/PLCl30wxKQNsq3pjDgu0mutKuu\n' \
218+
'5wIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAVEAIs/hLwTVCwpEXdoXR24LelNNuB\n' \
219+
'/8ptK6lyjE11XwfMN3yy7F2oB1lrA4rI3j9obpDsHDJBNB13bi/lKgvAcbIn/Tyu\n' \
220+
'RKThtUdPgxNnqDUyxnb3OofMF3gB8ePTu+jZpd3zrlEuxdl40ByATCSyOgR6DHMt\n' \
221+
'SDd+joypnOHFAeSM+V0AaTelXSCK9OAWSAp5e6S76a6lRx+D5Xl3hBedBI0tX59h\n' \
222+
'tEYNEGZaRElFU79WcEF0cH+ZW0+jJ95xE3thZffRz6QI6yF63m8aC9l9bbdJS2zg\n' \
223+
'Yv8W+lCZi//ODeOBUugr++z9uj+vGk47JDSpV0n4JOun3ALUDJ0gqmcS\n' \
224+
'-----END CERTIFICATE-----'
209225

210226
# consts for decorator pattern
211227
class DecoratorMode(Enum):

src/azure-cli/azure/cli/command_modules/acs/_help.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,10 @@
435435
- name: --k8s-support-plan
436436
type: string
437437
short-summary: Choose from "KubernetesOfficial" or "AKSLongTermSupport", with "AKSLongTermSupport" you get 1 extra year of CVE patchs.
438+
- name: --ca-certs --custom-ca-trust-certificates
439+
type: string
440+
short-summary: Path to a file containing up to 10 blank line separated certificates. Only valid for Linux nodes.
441+
long-summary: These certificates are used by Custom CA Trust feature and will be added to trust stores of nodes.
438442
- name: --enable-defender
439443
type: bool
440444
short-summary: Enable Microsoft Defender security profile.
@@ -857,6 +861,10 @@
857861
- name: --disable-defender
858862
type: bool
859863
short-summary: Disable defender profile.
864+
- name: --ca-certs --custom-ca-trust-certificates
865+
type: string
866+
short-summary: Path to a file containing up to 10 blank line separated certificates. Only valid for Linux nodes.
867+
long-summary: These certificates are used by Custom CA Trust feature and will be added to trust stores of nodes.
860868
- name: --defender-config
861869
type: string
862870
short-summary: Path to JSON file containing Microsoft Defender profile configurations.

src/azure-cli/azure/cli/command_modules/acs/_params.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@
100100
validate_disable_windows_outbound_nat,
101101
validate_crg_id,
102102
validate_azure_service_mesh_revision,
103-
validate_message_of_the_day)
103+
validate_message_of_the_day,
104+
validate_custom_ca_trust_certificates)
104105
from azure.cli.core.commands.parameters import (
105106
edge_zone_type, file_type, get_enum_type,
106107
get_resource_name_completion_list, get_three_state_flag, name_type,
@@ -366,6 +367,7 @@ def load_arguments(self, _):
366367
c.argument('enable_image_cleaner', action='store_true')
367368
c.argument('image_cleaner_interval_hours', type=int)
368369
c.argument('http_proxy_config')
370+
c.argument('custom_ca_trust_certificates', options_list=["--custom-ca-trust-certificates", "--ca-certs"], help="path to file containing list of new line separated CAs")
369371
c.argument('enable_keda', action='store_true')
370372
c.argument('enable_vpa', action='store_true', help='enable vertical pod autoscaler for cluster')
371373
c.argument('enable_azure_service_mesh',
@@ -556,6 +558,7 @@ def load_arguments(self, _):
556558
c.argument('disable_image_cleaner', action='store_true', validator=validate_image_cleaner_enable_disable_mutually_exclusive)
557559
c.argument('image_cleaner_interval_hours', type=int)
558560
c.argument('http_proxy_config')
561+
c.argument('custom_ca_trust_certificates', options_list=["--custom-ca-trust-certificates", "--ca-certs"], validator=validate_custom_ca_trust_certificates, help="path to file containing list of new line separated CAs")
559562
c.argument('enable_keda', action='store_true')
560563
c.argument('disable_keda', action='store_true')
561564
c.argument('enable_vpa', action='store_true', help='enable vertical pod autoscaler for cluster')

src/azure-cli/azure/cli/command_modules/acs/_validators.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
from azure.cli.core.util import CLIError
3030
from knack.log import get_logger
3131

32-
3332
logger = get_logger(__name__)
3433

3534

@@ -835,3 +834,10 @@ def validate_message_of_the_day(namespace):
835834
if namespace.os_type is not None and namespace.os_type != "Linux":
836835
raise ArgumentUsageError(
837836
'--message-of-the-day can only be set for linux nodepools')
837+
838+
def validate_custom_ca_trust_certificates(namespace):
839+
"""Validates Custom CA Trust Certificates can only be used on Linux."""
840+
if namespace.custom_ca_trust_certificates is not None and namespace.custom_ca_trust_certificates != "":
841+
if hasattr(namespace, 'os_type') and namespace.os_type != "Linux":
842+
raise ArgumentUsageError(
843+
'--custom-ca-trust-certificates can only be set for linux nodepools')

src/azure-cli/azure/cli/command_modules/acs/custom.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,7 @@ def aks_create(
574574
image_cleaner_interval_hours=None,
575575
enable_keda=False,
576576
enable_vpa=False,
577+
custom_ca_trust_certificates=None,
577578
# advanced networking
578579
enable_acns=None,
579580
disable_acns_observability=None,
@@ -777,6 +778,7 @@ def aks_update(
777778
enable_force_upgrade=False,
778779
disable_force_upgrade=False,
779780
upgrade_override_until=None,
781+
custom_ca_trust_certificates=None,
780782
# advanced networking
781783
disable_acns=None,
782784
enable_acns=None,

src/azure-cli/azure/cli/command_modules/acs/managed_cluster_decorator.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@
106106
from azure.cli.core.commands import AzCliCommand, LongRunningOperation
107107
from azure.cli.core.keys import is_valid_ssh_rsa_public_key
108108
from azure.cli.core.profiles import ResourceType
109-
from azure.cli.core.util import sdk_no_wait, truncate_text, get_file_json
109+
from azure.cli.core.util import sdk_no_wait, truncate_text, get_file_json, read_file_content
110110
from azure.core.exceptions import HttpResponseError
111111
from azure.mgmt.core.tools import is_valid_resource_id, parse_resource_id
112112
from knack.log import get_logger
@@ -882,6 +882,30 @@ def _get_disable_keda(self, enable_validation: bool = False) -> bool:
882882

883883
return disable_keda
884884

885+
def get_custom_ca_trust_certificates(self) -> Union[List[bytes], None]:
886+
"""Obtain the value of custom ca trust certificates.
887+
:return: List[str] or None
888+
"""
889+
custom_ca_certs_file_path = self.raw_param.get("custom_ca_trust_certificates")
890+
if not custom_ca_certs_file_path:
891+
return None
892+
if not os.path.isfile(custom_ca_certs_file_path):
893+
raise InvalidArgumentValueError(
894+
"{} is not valid file, or not accessible.".format(
895+
custom_ca_certs_file_path
896+
)
897+
)
898+
# CAs are supposed to be separated with a new line, we filter out empty strings (e.g. some stray new line). We only allow up to 10 CAs
899+
file_content = read_file_content(custom_ca_certs_file_path).split(os.linesep + os.linesep)
900+
certs = [str.encode(x) for x in file_content if len(x) > 1]
901+
if len(certs) > 10:
902+
raise InvalidArgumentValueError(
903+
"Only up to 10 new-line separated CAs can be passed, got {} instead.".format(
904+
len(certs)
905+
)
906+
)
907+
return certs
908+
885909
def get_snapshot_controller(self) -> Optional[ManagedClusterStorageProfileSnapshotController]:
886910
"""Obtain the value of storage_profile.snapshot_controller
887911
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIICljCCAX4CCQC9zUAgqqqrWzANBgkqhkiG9w0BAQsFADANMQswCQYDVQQGEwJQ
3+
TDAeFw0yMjA5MTQwNjIzMjdaFw0yMjA5MTUwNjIzMjdaMA0xCzAJBgNVBAYTAlBM
4+
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAopKNIIbvvcPCw9fc4KLX
5+
KDtRZobp5L+/1hCN+3OGhk5NvSTpSUrFifxqc0o3IF7YkO3K1n2jAvCMXO16Bf9b
6+
OAR7VkCrwGFVkXNjM4wvXAX8CNNvjqd1zDPXSKdE7Wd8k3fTzx6nGUM0UgljIPhH
7+
yh4a4Zujd5Ig2P/ZSX0pGJm47JTtMu7MDFHVM5wRWcCrN/H0TCYPIvEOs0B8AZxc
8+
p3TF7A6veT5U9pVhQ3Xl9JN6LvvLqPxG3ea10rdv9DYzaiXmSY3ujI3Ri1Q11uWC
9+
dtrFIpFu5cHW2OBW+jBXxL0v8xQmkxTLik4BR/PLCl30wxKQNsq3pjDgu0mutKuu
10+
5wIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAVEAIs/hLwTVCwpEXdoXR24LelNNuB
11+
/8ptK6lyjE11XwfMN3yy7F2oB1lrA4rI3j9obpDsHDJBNB13bi/lKgvAcbIn/Tyu
12+
RKThtUdPgxNnqDUyxnb3OofMF3gB8ePTu+jZpd3zrlEuxdl40ByATCSyOgR6DHMt
13+
SDd+joypnOHFAeSM+V0AaTelXSCK9OAWSAp5e6S76a6lRx+D5Xl3hBedBI0tX59h
14+
tEYNEGZaRElFU79WcEF0cH+ZW0+jJ95xE3thZffRz6QI6yF63m8aC9l9bbdJS2zg
15+
Yv8W+lCZi//ODeOBUugr++z9uj+vGk47JDSpV0n4JOun3ALUDJ0gqmcS
16+
-----END CERTIFICATE-----
17+
18+
-----BEGIN CERTIFICATE-----
19+
MIICljCCAX4CCQC9zUAgqqqrWzANBgkqhkiG9w0BAQsFADANMQswCQYDVQQGEwJQ
20+
TDAeFw0yMjA5MTQwNjIzMjdaFw0yMjA5MTUwNjIzMjdaMA0xCzAJBgNVBAYTAlBM
21+
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAopKNIIbvvcPCw9fc4KLX
22+
KDtRZobp5L+/1hCN+3OGhk5NvSTpSUrFifxqc0o3IF7YkO3K1n2jAvCMXO16Bf9b
23+
OAR7VkCrwGFVkXNjM4wvXAX8CNNvjqd1zDPXSKdE7Wd8k3fTzx6nGUM0UgljIPhH
24+
yh4a4Zujd5Ig2P/ZSX0pGJm47JTtMu7MDFHVM5wRWcCrN/H0TCYPIvEOs0B8AZxc
25+
p3TF7A6veT5U9pVhQ3Xl9JN6LvvLqPxG3ea10rdv9DYzaiXmSY3ujI3Ri1Q11uWC
26+
dtrFIpFu5cHW2OBW+jBXxL0v8xQmkxTLik4BR/PLCl30wxKQNsq3pjDgu0mutKuu
27+
5wIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAVEAIs/hLwTVCwpEXdoXR24LelNNuB
28+
/8ptK6lyjE11XwfMN3yy7F2oB1lrA4rI3j9obpDsHDJBNB13bi/lKgvAcbIn/Tyu
29+
RKThtUdPgxNnqDUyxnb3OofMF3gB8ePTu+jZpd3zrlEuxdl40ByATCSyOgR6DHMt
30+
SDd+joypnOHFAeSM+V0AaTelXSCK9OAWSAp5e6S76a6lRx+D5Xl3hBedBI0tX59h
31+
tEYNEGZaRElFU79WcEF0cH+ZW0+jJ95xE3thZffRz6QI6yF63m8aC9l9bbdJS2zg
32+
Yv8W+lCZi//ODeOBUugr++z9uj+vGk47JDSpV0n4JOun3ALUDJ0gqmcS
33+
-----END CERTIFICATE-----

0 commit comments

Comments
 (0)