qontract-reconcile 0.10.1rc471__py3-none-any.whl → 0.10.1rc473__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.
- {qontract_reconcile-0.10.1rc471.dist-info → qontract_reconcile-0.10.1rc473.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.1rc471.dist-info → qontract_reconcile-0.10.1rc473.dist-info}/RECORD +10 -9
- reconcile/gql_definitions/saas_auto_promotions_manager/__init__.py +0 -0
- reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_resources.py +30 -1
- reconcile/jira_permissions_validator.py +9 -2
- reconcile/test/test_terraform_cloudflare_resources.py +154 -18
- reconcile/utils/terrascript/cloudflare_resources.py +39 -0
- {qontract_reconcile-0.10.1rc471.dist-info → qontract_reconcile-0.10.1rc473.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.1rc471.dist-info → qontract_reconcile-0.10.1rc473.dist-info}/entry_points.txt +0 -0
- {qontract_reconcile-0.10.1rc471.dist-info → qontract_reconcile-0.10.1rc473.dist-info}/top_level.txt +0 -0
{qontract_reconcile-0.10.1rc471.dist-info → qontract_reconcile-0.10.1rc473.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: qontract-reconcile
|
3
|
-
Version: 0.10.
|
3
|
+
Version: 0.10.1rc473
|
4
4
|
Summary: Collection of tools to reconcile services with their desired state as defined in the app-interface DB.
|
5
5
|
Home-page: https://github.com/app-sre/qontract-reconcile
|
6
6
|
Author: Red Hat App-SRE Team
|
{qontract_reconcile-0.10.1rc471.dist-info → qontract_reconcile-0.10.1rc473.dist-info}/RECORD
RENAMED
@@ -44,7 +44,7 @@ reconcile/jenkins_roles.py,sha256=f8ELpZY36UjoaCpR_9LijQuIMuB6a7sVLFf_H1ct9Hc,44
|
|
44
44
|
reconcile/jenkins_webhooks.py,sha256=j8vhJMWcRhOdc9XzRSm0CPj84jsF3e4Syjm7r1BIsDE,1978
|
45
45
|
reconcile/jenkins_webhooks_cleaner.py,sha256=JsN_NVPfZJwv1JtSzZXDIHUqGiefL-DRffFnDGau9aY,1539
|
46
46
|
reconcile/jenkins_worker_fleets.py,sha256=PMNGOX0krubFjInPiFT0za0KCiWBLEcVDuXdKRd1BrE,5378
|
47
|
-
reconcile/jira_permissions_validator.py,sha256=
|
47
|
+
reconcile/jira_permissions_validator.py,sha256=kLRG9N441uN5lrLCx8QQBTS8knDdr87von_JjfyJ6X4,10177
|
48
48
|
reconcile/jira_watcher.py,sha256=eyOQ92t8TFi6gogfNTO448h_h1CUyr24E0MPHc51R-o,3617
|
49
49
|
reconcile/ldap_users.py,sha256=uEWQ0V41tN9KCZi4ZKPamjrJ6djSpdpvDBo7yJ0e7ZI,3008
|
50
50
|
reconcile/mr_client_gateway.py,sha256=WhjMd-sIXDFCV8-rt8CEjurJ5OYB1pOD0K3o0tZRXQg,1885
|
@@ -265,6 +265,7 @@ reconcile/gql_definitions/quay_membership/__init__.py,sha256=47DEQpj8HBSa-_TImW-
|
|
265
265
|
reconcile/gql_definitions/quay_membership/quay_membership.py,sha256=H2xHvdNr3K0QzB2dituwStUIWCqePt35dkgeUZycECM,2824
|
266
266
|
reconcile/gql_definitions/rhidp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
267
267
|
reconcile/gql_definitions/rhidp/organizations.py,sha256=8KVbWyvjDlvn-VGpYF06f4ZH6_PZMNCCZ8fa9W0s-Tk,2553
|
268
|
+
reconcile/gql_definitions/saas_auto_promotions_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
268
269
|
reconcile/gql_definitions/service_dependencies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
269
270
|
reconcile/gql_definitions/service_dependencies/jenkins_instance_fragment.py,sha256=gEcYRrdhGKG83cOpGEnecE0mCxpQHLRzXFCp5FBIhLA,699
|
270
271
|
reconcile/gql_definitions/service_dependencies/service_dependencies.py,sha256=CpMq9KjhFA61yniLo_11ypVInoeMBXbNmcY7_VAep-0,4700
|
@@ -289,7 +290,7 @@ reconcile/gql_definitions/terraform_cloudflare_dns/app_interface_cloudflare_dns_
|
|
289
290
|
reconcile/gql_definitions/terraform_cloudflare_dns/terraform_cloudflare_zones.py,sha256=uVZYu5EUcvdAQYBK5YKD0mjoMKDb5inSuCJrrOD5KpE,5704
|
290
291
|
reconcile/gql_definitions/terraform_cloudflare_resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
291
292
|
reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_accounts.py,sha256=WHMyQlosDCby7p1wWd3PXpmooSeEZyR8CgRDP49bunU,3641
|
292
|
-
reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_resources.py,sha256=
|
293
|
+
reconcile/gql_definitions/terraform_cloudflare_resources/terraform_cloudflare_resources.py,sha256=YWjhWTjOR7B-RsX5gPt1PbRfYDzxPqncNq4vmVHpIQ0,12313
|
293
294
|
reconcile/gql_definitions/terraform_cloudflare_users/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
294
295
|
reconcile/gql_definitions/terraform_cloudflare_users/app_interface_setting_cloudflare_and_vault.py,sha256=KFey-0ItgpGPeIwViGKqb55HAFJoKdi3eCNSIzf6Rc8,1960
|
295
296
|
reconcile/gql_definitions/terraform_cloudflare_users/terraform_cloudflare_roles.py,sha256=1KiTikTKSSRYmISN8tY29rJ_fVtgBnT7sK85IJjN420,4027
|
@@ -423,7 +424,7 @@ reconcile/test/test_sql_query.py,sha256=rC-lf1_isT9i2ZIV9W0hkUkLi2oBIjZMRMhk-6mV
|
|
423
424
|
reconcile/test/test_status_board.py,sha256=WdAq4pFoWWqcOcfgMzssZD3xfvT1QLrEHJqUARldtvA,7875
|
424
425
|
reconcile/test/test_terraform_aws_route53.py,sha256=xHggb8K1P76OyCfFcogbkmyKle-NlUylcbDnuv3IqvY,771
|
425
426
|
reconcile/test/test_terraform_cloudflare_dns.py,sha256=aQTXX8Vr4h9aWvJZTnpZEhMGYoBpT2d45ZxU_ECIQ6o,3425
|
426
|
-
reconcile/test/test_terraform_cloudflare_resources.py,sha256=
|
427
|
+
reconcile/test/test_terraform_cloudflare_resources.py,sha256=NK_uktyWihkQ3gMN4bCaKerpi43CXAVYGIKTfcz05rY,13550
|
427
428
|
reconcile/test/test_terraform_cloudflare_users.py,sha256=RAFtMMdqZha3jNnNNsqbNQQUDSqUzdoM63rCw7fs4Fo,27456
|
428
429
|
reconcile/test/test_terraform_repo.py,sha256=soKFJfF8tWIimDs39RQl3Hnh-Od-bR4PfnEA2s1UprM,11552
|
429
430
|
reconcile/test/test_terraform_resources.py,sha256=1ny_QSFuRjV9jxZY8EeT4NVJ5dMv7cLrEEIx_cBpjgk,9075
|
@@ -627,7 +628,7 @@ reconcile/utils/terraform/config.py,sha256=5UVrd563TMcvi4ooa5JvWVDW1I3bIWg484u79
|
|
627
628
|
reconcile/utils/terraform/config_client.py,sha256=py-Ree-QUYD6Hvng6bM40VgSuttteehIKNgwOSoJO1o,4706
|
628
629
|
reconcile/utils/terrascript/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
629
630
|
reconcile/utils/terrascript/cloudflare_client.py,sha256=EOmAnrgSUZz-UZB7x6TFd4WGk0huWZm2hh29Cueiyr8,10278
|
630
|
-
reconcile/utils/terrascript/cloudflare_resources.py,sha256=
|
631
|
+
reconcile/utils/terrascript/cloudflare_resources.py,sha256=ZvmFqE-Atki6ehMA4iirYqpml4bCPHdddq8lu58udGA,15952
|
631
632
|
reconcile/utils/terrascript/models.py,sha256=x9HReI0k71MHBpRTvvmPlE0G6rri5GTzPXM9cqyTWm0,475
|
632
633
|
reconcile/utils/terrascript/resources.py,sha256=bQzglnO41KZZEIeXYgi-qlup1p8R03Qyx_V944LRPsc,1391
|
633
634
|
release/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -649,8 +650,8 @@ tools/test/test_app_interface_metrics_exporter.py,sha256=SX7qL3D1SIRKFo95FoQztvf
|
|
649
650
|
tools/test/test_qontract_cli.py,sha256=awwTHEc2DWlykuqGIYM0WOBoSL0KRnOraCLk3C7izis,1401
|
650
651
|
tools/test/test_sd_app_sre_alert_report.py,sha256=v363r9zM7__0kR5K6mvJoGFcM9BvE33fWAayrqkpojA,2116
|
651
652
|
tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
|
652
|
-
qontract_reconcile-0.10.
|
653
|
-
qontract_reconcile-0.10.
|
654
|
-
qontract_reconcile-0.10.
|
655
|
-
qontract_reconcile-0.10.
|
656
|
-
qontract_reconcile-0.10.
|
653
|
+
qontract_reconcile-0.10.1rc473.dist-info/METADATA,sha256=Rnigg-CBRz8a3ixHxvm6IblRrV35SbamdffbAThCeJM,2348
|
654
|
+
qontract_reconcile-0.10.1rc473.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
655
|
+
qontract_reconcile-0.10.1rc473.dist-info/entry_points.txt,sha256=rTjAv28I_CHLM8ID3OPqMI_suoQ9s7tFbim4aYjn9kk,376
|
656
|
+
qontract_reconcile-0.10.1rc473.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
|
657
|
+
qontract_reconcile-0.10.1rc473.dist-info/RECORD,,
|
File without changes
|
@@ -67,6 +67,7 @@ query TerraformCloudflareResources {
|
|
67
67
|
}
|
68
68
|
managedExternalResources
|
69
69
|
externalResources {
|
70
|
+
provider
|
70
71
|
... on NamespaceTerraformProviderResourceCloudflare_v1 {
|
71
72
|
provider
|
72
73
|
provisioner {
|
@@ -128,6 +129,20 @@ query TerraformCloudflareResources {
|
|
128
129
|
cloudflare_branding
|
129
130
|
wait_for_active_status
|
130
131
|
}
|
132
|
+
custom_ssl_certificates {
|
133
|
+
identifier
|
134
|
+
type
|
135
|
+
bundle_method
|
136
|
+
geo_restrictions
|
137
|
+
certificate_secret {
|
138
|
+
certificate {
|
139
|
+
... VaultSecret
|
140
|
+
}
|
141
|
+
key {
|
142
|
+
... VaultSecret
|
143
|
+
}
|
144
|
+
}
|
145
|
+
}
|
131
146
|
}
|
132
147
|
... on NamespaceTerraformResourceLogpushOwnershipChallenge_v1
|
133
148
|
{
|
@@ -190,7 +205,7 @@ class ClusterV1(ConfiguredBaseModel):
|
|
190
205
|
|
191
206
|
|
192
207
|
class NamespaceExternalResourceV1(ConfiguredBaseModel):
|
193
|
-
|
208
|
+
provider: str = Field(..., alias="provider")
|
194
209
|
|
195
210
|
|
196
211
|
class CloudflareAccountV1(ConfiguredBaseModel):
|
@@ -258,6 +273,19 @@ class CloudflareZoneCertificateV1(ConfiguredBaseModel):
|
|
258
273
|
wait_for_active_status: Optional[bool] = Field(..., alias="wait_for_active_status")
|
259
274
|
|
260
275
|
|
276
|
+
class CertificateSecretV1(ConfiguredBaseModel):
|
277
|
+
certificate: VaultSecret = Field(..., alias="certificate")
|
278
|
+
key: VaultSecret = Field(..., alias="key")
|
279
|
+
|
280
|
+
|
281
|
+
class CloudflareCustomSSLCertificateV1(ConfiguredBaseModel):
|
282
|
+
identifier: str = Field(..., alias="identifier")
|
283
|
+
q_type: str = Field(..., alias="type")
|
284
|
+
bundle_method: Optional[str] = Field(..., alias="bundle_method")
|
285
|
+
geo_restrictions: Optional[str] = Field(..., alias="geo_restrictions")
|
286
|
+
certificate_secret: CertificateSecretV1 = Field(..., alias="certificate_secret")
|
287
|
+
|
288
|
+
|
261
289
|
class NamespaceTerraformResourceCloudflareZoneV1(NamespaceTerraformResourceCloudflareV1):
|
262
290
|
identifier: str = Field(..., alias="identifier")
|
263
291
|
zone: str = Field(..., alias="zone")
|
@@ -270,6 +298,7 @@ class NamespaceTerraformResourceCloudflareZoneV1(NamespaceTerraformResourceCloud
|
|
270
298
|
records: Optional[list[CloudflareDnsRecordV1]] = Field(..., alias="records")
|
271
299
|
workers: Optional[list[CloudflareZoneWorkerV1]] = Field(..., alias="workers")
|
272
300
|
certificates: Optional[list[CloudflareZoneCertificateV1]] = Field(..., alias="certificates")
|
301
|
+
custom_ssl_certificates: Optional[list[CloudflareCustomSSLCertificateV1]] = Field(..., alias="custom_ssl_certificates")
|
273
302
|
|
274
303
|
|
275
304
|
class NamespaceTerraformResourceLogpushOwnershipChallengeV1(NamespaceTerraformResourceCloudflareV1):
|
@@ -128,16 +128,23 @@ def board_is_valid(
|
|
128
128
|
error |= ValidationError.INVALID_SECURITY_LEVEL
|
129
129
|
|
130
130
|
project_priorities = jira.project_priority_scheme()
|
131
|
+
# get the priority names from the project priorities ids
|
132
|
+
project_priorities_names = [
|
133
|
+
p_name
|
134
|
+
for project_p_id in project_priorities
|
135
|
+
for p_name, p_id in jira_server_priorities.items()
|
136
|
+
if p_id == project_p_id
|
137
|
+
]
|
131
138
|
for priority in board.severity_priority_mappings.mappings:
|
132
139
|
if priority.priority not in jira_server_priorities:
|
133
140
|
logging.error(
|
134
|
-
f"[{board.name}] {priority.priority} is not a valid Jira priority. Valid priorities: {
|
141
|
+
f"[{board.name}] {priority.priority} is not a valid Jira priority. Valid priorities: {project_priorities_names}"
|
135
142
|
)
|
136
143
|
error |= ValidationError.INVALID_PRIORITY
|
137
144
|
continue
|
138
145
|
if jira_server_priorities[priority.priority] not in project_priorities:
|
139
146
|
logging.error(
|
140
|
-
f"[{board.name}] {priority.priority} is not a valid priority in project. Valid priorities: {
|
147
|
+
f"[{board.name}] {priority.priority} is not a valid priority in project. Valid priorities: {project_priorities_names}"
|
141
148
|
)
|
142
149
|
error |= ValidationError.INVALID_PRIORITY
|
143
150
|
except JIRAError as e:
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import logging
|
2
|
+
from unittest.mock import call
|
2
3
|
|
3
4
|
import pytest
|
4
5
|
|
@@ -18,7 +19,9 @@ from reconcile.gql_definitions.terraform_cloudflare_resources.terraform_cloudfla
|
|
18
19
|
CloudflareAccountV1 as CFAccountV1,
|
19
20
|
)
|
20
21
|
from reconcile.gql_definitions.terraform_cloudflare_resources.terraform_cloudflare_resources import (
|
22
|
+
CertificateSecretV1,
|
21
23
|
CloudflareAccountV1,
|
24
|
+
CloudflareCustomSSLCertificateV1,
|
22
25
|
CloudflareDnsRecordV1,
|
23
26
|
CloudflareZoneArgoV1,
|
24
27
|
CloudflareZoneCacheReserveV1,
|
@@ -31,6 +34,10 @@ from reconcile.gql_definitions.terraform_cloudflare_resources.terraform_cloudfla
|
|
31
34
|
NamespaceV1,
|
32
35
|
TerraformCloudflareResourcesQueryData,
|
33
36
|
)
|
37
|
+
from reconcile.status import ExitCodes
|
38
|
+
from reconcile.utils.secret_reader import (
|
39
|
+
SecretReaderBase,
|
40
|
+
)
|
34
41
|
|
35
42
|
|
36
43
|
@pytest.fixture
|
@@ -72,7 +79,7 @@ def external_resources(provisioner_config):
|
|
72
79
|
provisioner=provisioner_config,
|
73
80
|
resources=[
|
74
81
|
NamespaceTerraformResourceCloudflareZoneV1(
|
75
|
-
provider="
|
82
|
+
provider="zone",
|
76
83
|
identifier="testzone-com",
|
77
84
|
zone="testzone.com",
|
78
85
|
plan="enterprise",
|
@@ -115,6 +122,28 @@ def external_resources(provisioner_config):
|
|
115
122
|
wait_for_active_status=False,
|
116
123
|
)
|
117
124
|
],
|
125
|
+
custom_ssl_certificates=[
|
126
|
+
CloudflareCustomSSLCertificateV1(
|
127
|
+
identifier="testcustomssl",
|
128
|
+
type="legacy_custom",
|
129
|
+
bundle_method="ubiquitous",
|
130
|
+
geo_restrictions="us",
|
131
|
+
certificate_secret=CertificateSecretV1(
|
132
|
+
certificate=VaultSecret(
|
133
|
+
path="certificate/secret/cert/path",
|
134
|
+
field="certificate.crt",
|
135
|
+
format="plain",
|
136
|
+
version=1,
|
137
|
+
),
|
138
|
+
key=VaultSecret(
|
139
|
+
path="certificate/secret/key/path",
|
140
|
+
field="certificate.key",
|
141
|
+
format="plain",
|
142
|
+
version=1,
|
143
|
+
),
|
144
|
+
),
|
145
|
+
)
|
146
|
+
],
|
118
147
|
),
|
119
148
|
],
|
120
149
|
)
|
@@ -126,12 +155,51 @@ def mock_gql(mocker):
|
|
126
155
|
|
127
156
|
|
128
157
|
@pytest.fixture
|
129
|
-
def
|
130
|
-
|
158
|
+
def mock_app_interface_vault_settings(mocker):
|
159
|
+
mocked_app_interface_vault_settings = mocker.patch(
|
131
160
|
"reconcile.terraform_cloudflare_resources.get_app_interface_vault_settings",
|
132
161
|
autospec=True,
|
133
162
|
)
|
134
|
-
|
163
|
+
mocked_app_interface_vault_settings.return_value = AppInterfaceSettingsV1(
|
164
|
+
vault=True
|
165
|
+
)
|
166
|
+
|
167
|
+
|
168
|
+
def secret_reader_side_effect(*args):
|
169
|
+
if {
|
170
|
+
"path": "aws-account-path",
|
171
|
+
"field": "token",
|
172
|
+
"version": 1,
|
173
|
+
"q_format": "plain",
|
174
|
+
} == args[0]:
|
175
|
+
aws_acct_creds = {}
|
176
|
+
aws_acct_creds["aws_access_key_id"] = "key_id"
|
177
|
+
aws_acct_creds["aws_secret_access_key"] = "access_key"
|
178
|
+
return aws_acct_creds
|
179
|
+
|
180
|
+
if {
|
181
|
+
"path": "cf-account-path",
|
182
|
+
"field": "key",
|
183
|
+
"version": 1,
|
184
|
+
"q_format": "plain",
|
185
|
+
} == args[0]:
|
186
|
+
cf_acct_creds = {}
|
187
|
+
cf_acct_creds["api_token"] = "api_token"
|
188
|
+
cf_acct_creds["account_id"] = "account_id"
|
189
|
+
return cf_acct_creds
|
190
|
+
|
191
|
+
|
192
|
+
@pytest.fixture
|
193
|
+
def mock_create_secret_reader(mocker):
|
194
|
+
secret_reader = mocker.Mock(SecretReaderBase)
|
195
|
+
secret_reader.read_all_secret.side_effect = secret_reader_side_effect
|
196
|
+
|
197
|
+
mocked_create_secret_reader = mocker.patch(
|
198
|
+
"reconcile.terraform_cloudflare_resources.create_secret_reader",
|
199
|
+
autospec=True,
|
200
|
+
)
|
201
|
+
|
202
|
+
mocked_create_secret_reader.return_value = secret_reader
|
135
203
|
|
136
204
|
|
137
205
|
@pytest.fixture
|
@@ -147,26 +215,27 @@ def mock_cloudflare_accounts(mocker):
|
|
147
215
|
name="cfaccount",
|
148
216
|
providerVersion="0.33.x",
|
149
217
|
apiCredentials=VaultSecret(
|
150
|
-
path="
|
218
|
+
path="cf-account-path",
|
151
219
|
field="key",
|
152
220
|
version=1,
|
153
|
-
format="
|
221
|
+
format="plain",
|
154
222
|
),
|
155
223
|
terraformStateAccount=AWSAccountV1(
|
156
224
|
name="awsaccoutn",
|
157
225
|
automationToken=VaultSecret(
|
158
|
-
path="
|
226
|
+
path="aws-account-path",
|
159
227
|
field="token",
|
160
228
|
version=1,
|
161
|
-
format="",
|
229
|
+
format="plain",
|
162
230
|
),
|
163
231
|
terraformState=TerraformStateAWSV1(
|
164
|
-
provider="",
|
165
|
-
bucket="",
|
166
|
-
region="",
|
232
|
+
provider="s3",
|
233
|
+
bucket="app-interface",
|
234
|
+
region="us-east-1",
|
167
235
|
integrations=[
|
168
236
|
AWSTerraformStateIntegrationsV1(
|
169
|
-
integration="terraform-cloudflare-resources",
|
237
|
+
integration="terraform-cloudflare-resources",
|
238
|
+
key="somekey.tfstate",
|
170
239
|
)
|
171
240
|
],
|
172
241
|
),
|
@@ -183,16 +252,29 @@ def mock_cloudflare_accounts(mocker):
|
|
183
252
|
|
184
253
|
|
185
254
|
@pytest.fixture
|
186
|
-
def mock_cloudflare_resources(mocker,
|
255
|
+
def mock_cloudflare_resources(mocker, query_data):
|
187
256
|
mocked_cloudflare_resources = mocker.patch(
|
188
257
|
"reconcile.terraform_cloudflare_resources.terraform_cloudflare_resources",
|
189
258
|
autospec=True,
|
190
259
|
)
|
191
|
-
mocked_cloudflare_resources.query.return_value =
|
260
|
+
mocked_cloudflare_resources.query.return_value = query_data
|
261
|
+
|
262
|
+
|
263
|
+
@pytest.fixture
|
264
|
+
def mock_terraform_client(mocker):
|
265
|
+
mocked_tf_client = mocker.patch(
|
266
|
+
"reconcile.terraform_cloudflare_resources.TerraformClient", autospec=True
|
267
|
+
)
|
268
|
+
mocked_tf_client.return_value.plan.return_value = False, None
|
269
|
+
return mocked_tf_client
|
192
270
|
|
193
271
|
|
194
272
|
def test_cloudflare_accounts_validation(
|
195
|
-
mocker,
|
273
|
+
mocker,
|
274
|
+
caplog,
|
275
|
+
mock_gql,
|
276
|
+
mock_app_interface_vault_settings,
|
277
|
+
mock_cloudflare_resources,
|
196
278
|
):
|
197
279
|
# Mocking accounts with an empty response
|
198
280
|
mocked_cloudflare_accounts = mocker.patch(
|
@@ -212,14 +294,17 @@ def test_cloudflare_accounts_validation(
|
|
212
294
|
|
213
295
|
|
214
296
|
def test_namespace_validation(
|
215
|
-
mocker,
|
297
|
+
mocker,
|
298
|
+
caplog,
|
299
|
+
mock_gql,
|
300
|
+
mock_app_interface_vault_settings,
|
301
|
+
mock_cloudflare_accounts,
|
216
302
|
):
|
217
303
|
# Mocking resources without namespaces
|
218
304
|
mocked_resources = mocker.patch(
|
219
305
|
"reconcile.terraform_cloudflare_resources.terraform_cloudflare_resources",
|
220
306
|
autospec=True,
|
221
307
|
)
|
222
|
-
|
223
308
|
mocked_resources.query.return_value = TerraformCloudflareResourcesQueryData(
|
224
309
|
namespaces=[],
|
225
310
|
)
|
@@ -233,7 +318,11 @@ def test_namespace_validation(
|
|
233
318
|
|
234
319
|
|
235
320
|
def test_cloudflare_namespace_validation(
|
236
|
-
mocker,
|
321
|
+
mocker,
|
322
|
+
caplog,
|
323
|
+
mock_gql,
|
324
|
+
mock_app_interface_vault_settings,
|
325
|
+
mock_cloudflare_accounts,
|
237
326
|
):
|
238
327
|
# Mocking resources without cloudflare namespaces
|
239
328
|
mocked_resources = mocker.patch(
|
@@ -269,3 +358,50 @@ def test_cloudflare_namespace_validation(
|
|
269
358
|
assert ["No cloudflare namespaces were detected, nothing to do."] == [
|
270
359
|
rec.message for rec in caplog.records
|
271
360
|
]
|
361
|
+
|
362
|
+
|
363
|
+
def custom_ssl_secret_reader_side_effect(*args):
|
364
|
+
"""For use of secret_reader inside cloudflare client"""
|
365
|
+
if {
|
366
|
+
"path": "certificate/secret/cert/path",
|
367
|
+
"field": "certificate.crt",
|
368
|
+
"version": 1,
|
369
|
+
"q_format": "plain",
|
370
|
+
} == args[0]:
|
371
|
+
return "----- CERTIFICATE -----"
|
372
|
+
|
373
|
+
if {
|
374
|
+
"path": "certificate/secret/cert/path",
|
375
|
+
"field": "certificate.key",
|
376
|
+
"version": 1,
|
377
|
+
"q_format": "plain",
|
378
|
+
} == args[0]:
|
379
|
+
return "----- KEY -----"
|
380
|
+
|
381
|
+
|
382
|
+
def test_terraform_cloudflare_resources_dry_run(
|
383
|
+
mocker,
|
384
|
+
mock_gql,
|
385
|
+
mock_create_secret_reader,
|
386
|
+
mock_terraform_client,
|
387
|
+
mock_app_interface_vault_settings,
|
388
|
+
mock_cloudflare_accounts,
|
389
|
+
mock_cloudflare_resources,
|
390
|
+
):
|
391
|
+
# Mocking vault settings and secret reader inside cloudflare_client
|
392
|
+
mocker.patch(
|
393
|
+
"reconcile.utils.terrascript.cloudflare_resources.get_app_interface_vault_settings",
|
394
|
+
atospec=True,
|
395
|
+
)
|
396
|
+
secret_reader = mocker.Mock(SecretReaderBase)
|
397
|
+
secret_reader.read.side_effect = custom_ssl_secret_reader_side_effect
|
398
|
+
create_secret_reader = mocker.patch(
|
399
|
+
"reconcile.utils.terrascript.cloudflare_resources.create_secret_reader",
|
400
|
+
autospec=True,
|
401
|
+
)
|
402
|
+
create_secret_reader.return_value = secret_reader
|
403
|
+
with pytest.raises(SystemExit) as sample:
|
404
|
+
integ.run(True, None, False, 10)
|
405
|
+
assert sample.value.code == ExitCodes.SUCCESS
|
406
|
+
assert mock_terraform_client.called is True
|
407
|
+
assert call().apply() not in mock_terraform_client.method_calls
|
@@ -16,6 +16,7 @@ from terrascript import (
|
|
16
16
|
from terrascript.resource import (
|
17
17
|
cloudflare_account_member,
|
18
18
|
cloudflare_argo,
|
19
|
+
cloudflare_custom_ssl,
|
19
20
|
cloudflare_logpull_retention,
|
20
21
|
cloudflare_logpush_job,
|
21
22
|
cloudflare_logpush_ownership_challenge,
|
@@ -186,6 +187,38 @@ class CloudflareZoneTerrascriptResource(TerrascriptResource):
|
|
186
187
|
|
187
188
|
return resources
|
188
189
|
|
190
|
+
def _create_cloudflare_custom_ssl_certificates(
|
191
|
+
self,
|
192
|
+
zone: Resource,
|
193
|
+
zone_custom_ssl: Iterable[MutableMapping[str, Any]],
|
194
|
+
) -> list[Union[Resource, Output]]:
|
195
|
+
vault_settings = get_app_interface_vault_settings()
|
196
|
+
secret_reader = create_secret_reader(use_vault=vault_settings.vault)
|
197
|
+
|
198
|
+
resources = []
|
199
|
+
for cert_values in zone_custom_ssl:
|
200
|
+
identifier = safe_resource_id(cert_values.pop("identifier"))
|
201
|
+
certificate_secret = cert_values.pop("certificate_secret")
|
202
|
+
certificate = secret_reader.read(certificate_secret.pop("certificate"))
|
203
|
+
key = secret_reader.read(certificate_secret.pop("key"))
|
204
|
+
custom_ssl_values: dict[Any, Any] = {
|
205
|
+
"zone_id": f"${{{zone.id}}}",
|
206
|
+
"depends_on": self._get_dependencies([zone]),
|
207
|
+
"custom_ssl_options": {
|
208
|
+
"bundle_method": cert_values.pop("bundle_method", "ubiquitous"),
|
209
|
+
"type": cert_values.pop("type"),
|
210
|
+
"certificate": certificate,
|
211
|
+
"private_key": key,
|
212
|
+
},
|
213
|
+
}
|
214
|
+
if cert_values.get("geo_restrictions", None):
|
215
|
+
custom_ssl_values["custom_ssl_options"]["geo_restrictions"] = (
|
216
|
+
cert_values.get("geo_resrtictions")
|
217
|
+
)
|
218
|
+
custom_ssl = cloudflare_custom_ssl(identifier, **custom_ssl_values)
|
219
|
+
resources.append(custom_ssl)
|
220
|
+
return resources
|
221
|
+
|
189
222
|
def populate(self) -> list[Union[Resource, Output]]:
|
190
223
|
resources = []
|
191
224
|
|
@@ -202,6 +235,7 @@ class CloudflareZoneTerrascriptResource(TerrascriptResource):
|
|
202
235
|
zone_records = values.pop("records", [])
|
203
236
|
zone_workers = values.pop("workers", [])
|
204
237
|
zone_certs = values.pop("certificates", [])
|
238
|
+
zone_custom_ssl = values.pop("custom_ssl_certificates", [])
|
205
239
|
|
206
240
|
zone_values = {
|
207
241
|
"account_id": "${var.account_id}",
|
@@ -268,6 +302,11 @@ class CloudflareZoneTerrascriptResource(TerrascriptResource):
|
|
268
302
|
|
269
303
|
resources.extend(self._create_cloudflare_certificate_pack(zone, zone_certs))
|
270
304
|
|
305
|
+
if zone_custom_ssl:
|
306
|
+
resources.extend(
|
307
|
+
self._create_cloudflare_custom_ssl_certificates(zone, zone_custom_ssl)
|
308
|
+
)
|
309
|
+
|
271
310
|
return resources
|
272
311
|
|
273
312
|
|
File without changes
|
File without changes
|
{qontract_reconcile-0.10.1rc471.dist-info → qontract_reconcile-0.10.1rc473.dist-info}/top_level.txt
RENAMED
File without changes
|