Skip to content

Commit 930ca7e

Browse files
Add Cloudera ssl config parameters and functionality (#17649)
* Added ssl config parameters and functionality * changelog * Add test_client_ssl --------- Co-authored-by: Steven Yuen <steven.yuen@datadoghq.com>
1 parent 7d8df00 commit 930ca7e

File tree

9 files changed

+112
-12
lines changed

9 files changed

+112
-12
lines changed

cloudera/assets/configuration/spec.yaml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,33 @@ files:
3434
3535
value:
3636
type: string
37+
- name: verify_ssl
38+
description: Enable SSL/TLS encryption for the check.
39+
value:
40+
default: true
41+
type: boolean
42+
example: true
43+
- name: ssl_ca_cert
44+
description: Path to the file containing the CA certificates to trust.
45+
value:
46+
example: <CERT_PATH>
47+
type: string
48+
- name: cert_file
49+
description: Path to the file from which the local certificates can be loaded.
50+
value:
51+
example: <CERT_FILE_PATH>
52+
type: string
53+
- name: key_file
54+
description: Path to the file from which to load the private key.
55+
value:
56+
example: <KEY_FILE_PATH>
57+
type: string
3758
- name: max_parallel_requests
3859
description: |
3960
The maximum number of requests to Cloudera Manager that are allowed in parallel.
4061
hidden: true
4162
value:
63+
default: 4
4264
type: integer
4365
example: 100
4466
- name: clusters

cloudera/changelog.d/17649.added

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add Cloudera ssl config parameters and functionality

cloudera/datadog_checks/cloudera/api/factory.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ def make_api(check) -> Api:
1919
'workload_username': check.shared_config.workload_username,
2020
'workload_password': check.shared_config.workload_password,
2121
'max_parallel_requests': check.config.max_parallel_requests,
22+
'verify_ssl': check.config.verify_ssl,
23+
'ssl_ca_cert': check.config.ssl_ca_cert,
24+
'cert_file': check.config.cert_file,
25+
'key_file': check.config.key_file,
2226
},
2327
)
2428
if not client:

cloudera/datadog_checks/cloudera/client/cm_client.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ def __init__(self, log, **kwargs):
2525
cm_client.configuration.username = kwargs.get('workload_username')
2626
cm_client.configuration.password = kwargs.get('workload_password')
2727
self._client = cm_client.ApiClient(kwargs.get('api_url'))
28+
cm_client.configuration.verify_ssl = kwargs.get('verify_ssl')
29+
cm_client.configuration.ssl_ca_cert = kwargs.get('ssl_ca_cert')
30+
cm_client.configuration.cert_file = kwargs.get('cert_file')
31+
cm_client.configuration.key_file = kwargs.get('key_file')
2832
self._client.rest_client = RESTClientObject(maxsize=kwargs.get('max_parallel_requests'))
2933

3034
def get_version(self) -> Version:

cloudera/datadog_checks/cloudera/config_models/defaults.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,12 @@ def instance_empty_default_hostname():
2121

2222

2323
def instance_max_parallel_requests():
24-
return 100
24+
return 4
2525

2626

2727
def instance_min_collection_interval():
2828
return 15
29+
30+
31+
def instance_verify_ssl():
32+
return True

cloudera/datadog_checks/cloudera/config_models/instance.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,20 @@ class InstanceConfig(BaseModel):
5656
frozen=True,
5757
)
5858
api_url: str
59+
cert_file: Optional[str] = None
5960
cloudera_client: Optional[str] = None
6061
clusters: Optional[Clusters] = None
6162
custom_queries: Optional[tuple[CustomQuery, ...]] = None
6263
disable_generic_tags: Optional[bool] = None
6364
empty_default_hostname: Optional[bool] = None
65+
key_file: Optional[str] = None
6466
max_parallel_requests: Optional[int] = None
6567
metric_patterns: Optional[MetricPatterns] = None
6668
min_collection_interval: Optional[float] = None
6769
service: Optional[str] = None
70+
ssl_ca_cert: Optional[str] = None
6871
tags: Optional[tuple[str, ...]] = None
72+
verify_ssl: Optional[bool] = None
6973

7074
@model_validator(mode='before')
7175
def _initial_validation(cls, values):

cloudera/datadog_checks/cloudera/data/conf.yaml.example

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,26 @@ instances:
3636
#
3737
- api_url: <API_URL>
3838

39+
## @param verify_ssl - boolean - optional - default: true
40+
## Enable SSL/TLS encryption for the check.
41+
#
42+
# verify_ssl: true
43+
44+
## @param ssl_ca_cert - string - optional
45+
## Path to the file containing the CA certificates to trust.
46+
#
47+
# ssl_ca_cert: <CERT_PATH>
48+
49+
## @param cert_file - string - optional
50+
## Path to the file from which the local certificates can be loaded.
51+
#
52+
# cert_file: <CERT_FILE_PATH>
53+
54+
## @param key_file - string - optional
55+
## Path to the file from which to load the private key.
56+
#
57+
# key_file: <KEY_FILE_PATH>
58+
3959
## @param clusters - mapping - optional
4060
## Optional configuration to indicate the clusters that we want to be processed. If not configured,
4161
## all clusters will be processed.

cloudera/tests/conftest.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
from copy import deepcopy
66

7+
import mock
78
import pytest
9+
from packaging.version import Version
810

911
from datadog_checks.cloudera import ClouderaCheck
1012
from datadog_checks.dev import docker_run
@@ -37,3 +39,27 @@ def config():
3739
@pytest.fixture(scope='session')
3840
def cloudera_check():
3941
return lambda instance: deepcopy(ClouderaCheck('cloudera', init_config=common.INIT_CONFIG, instances=[instance]))
42+
43+
44+
class MockCmClient:
45+
def __init__(self, log, **kwargs):
46+
self.log = log
47+
self.kwargs = kwargs
48+
49+
def get_version(self):
50+
return Version('7.0.0')
51+
52+
def read_clusters(self):
53+
return []
54+
55+
def read_events(self, query):
56+
return []
57+
58+
59+
@pytest.fixture
60+
def cloudera_cm_client():
61+
def cm_client(log, **kwargs):
62+
return MockCmClient(log, **kwargs)
63+
64+
with mock.patch('datadog_checks.cloudera.client.factory.CmClient', side_effect=cm_client) as mock_cm_client:
65+
yield mock_cm_client

cloudera/tests/test_unit_client.py

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
import mock
88
import pytest
9-
from packaging.version import Version
109

1110
from datadog_checks.base.types import ServiceCheck
1211

@@ -100,6 +99,7 @@
10099
'cloudera_client cm_client with custom tags',
101100
],
102101
)
102+
@pytest.mark.usefixtures('cloudera_cm_client')
103103
def test_client(
104104
aggregator,
105105
dd_run_check,
@@ -108,16 +108,7 @@ def test_client(
108108
expected_exception,
109109
expected_service_checks,
110110
):
111-
with expected_exception, mock.patch(
112-
'datadog_checks.cloudera.client.cm_client.CmClient.get_version',
113-
return_value=Version('7.0.0'),
114-
), mock.patch(
115-
'datadog_checks.cloudera.client.cm_client.CmClient.read_clusters',
116-
return_value=[],
117-
), mock.patch(
118-
'datadog_checks.cloudera.client.cm_client.CmClient.read_events',
119-
return_value=[],
120-
):
111+
with expected_exception:
121112
check = cloudera_check(instance)
122113
dd_run_check(check)
123114
for expected_service_check in expected_service_checks:
@@ -128,3 +119,27 @@ def test_client(
128119
message=expected_service_check.get('message'),
129120
tags=expected_service_check.get('tags'),
130121
)
122+
123+
124+
def test_client_ssl(dd_run_check, cloudera_check, cloudera_cm_client):
125+
instance = {
126+
'api_url': 'http://localhost:8080/api/v48/',
127+
'cloudera_client': 'cm_client',
128+
'verify_ssl': True,
129+
'ssl_ca_cert': 'ssl_ca_cert_path',
130+
'cert_file': 'cert_file_path',
131+
'key_file': 'key_file_path',
132+
}
133+
check = cloudera_check(instance)
134+
dd_run_check(check)
135+
cloudera_cm_client.assert_called_once_with(
136+
mock.ANY,
137+
api_url='http://localhost:8080/api/v48/',
138+
workload_username='~',
139+
workload_password='~',
140+
max_parallel_requests=4,
141+
verify_ssl=True,
142+
ssl_ca_cert='ssl_ca_cert_path',
143+
cert_file='cert_file_path',
144+
key_file='key_file_path',
145+
)

0 commit comments

Comments
 (0)