|
30 | 30 | JoinAuthEntry, |
31 | 31 | ResourceEntry, |
32 | 32 | ShareEntry, |
| 33 | + TLSCredentialEntry, |
33 | 34 | UsersAndGroupsEntry, |
34 | 35 | resource_entry, |
35 | 36 | resource_key, |
@@ -163,6 +164,7 @@ def prune_linked_entries(self) -> None: |
163 | 164 | cids = set(ClusterEntry.ids(self)) |
164 | 165 | self._prune(cids, JoinAuthEntry, resources.JoinAuth) |
165 | 166 | self._prune(cids, UsersAndGroupsEntry, resources.UsersAndGroups) |
| 167 | + self._prune(cids, TLSCredentialEntry, resources.TLSCredential) |
166 | 168 |
|
167 | 169 |
|
168 | 170 | def auth_refs(cluster: resources.Cluster) -> Collection[str]: |
@@ -532,6 +534,72 @@ def _check_users_and_groups_present( |
532 | 534 | ) |
533 | 535 |
|
534 | 536 |
|
| 537 | +@cross_check_resource.register |
| 538 | +def _check_tls_credential_resource( |
| 539 | + resource: resources.TLSCredential, staging: Staging, **_kw: Any |
| 540 | +) -> None: |
| 541 | + """Check that the tls credential resource can be updated.""" |
| 542 | + if resource.intent == Intent.PRESENT: |
| 543 | + return _check_tls_credential_present(resource, staging) |
| 544 | + return _check_tls_credential_removed(resource, staging) |
| 545 | + |
| 546 | + |
| 547 | +def _check_tls_credential_removed( |
| 548 | + tls_cred: resources.TLSCredential, staging: Staging |
| 549 | +) -> None: |
| 550 | + cids = set(ClusterEntry.ids(staging)) |
| 551 | + refs_in_use: Dict[str, List[str]] = {} |
| 552 | + for cluster_id in cids: |
| 553 | + cluster = staging.get_cluster(cluster_id) |
| 554 | + for ref in tls_refs(cluster): |
| 555 | + refs_in_use.setdefault(ref, []).append(cluster_id) |
| 556 | + log.debug('refs_in_use: %r', refs_in_use) |
| 557 | + if tls_cred.tls_credential_id in refs_in_use: |
| 558 | + raise ErrorResult( |
| 559 | + tls_cred, |
| 560 | + msg='tls credential resource in use by clusters', |
| 561 | + status={ |
| 562 | + 'clusters': refs_in_use[tls_cred.tls_credential_id], |
| 563 | + }, |
| 564 | + ) |
| 565 | + |
| 566 | + |
| 567 | +def _check_tls_credential_present( |
| 568 | + tls_cred: resources.TLSCredential, staging: Staging |
| 569 | +) -> None: |
| 570 | + # TODO: dedupe this logic across join auth and usersgroups |
| 571 | + if tls_cred.linked_to_cluster: |
| 572 | + cids = set(ClusterEntry.ids(staging)) |
| 573 | + if tls_cred.linked_to_cluster not in cids: |
| 574 | + raise ErrorResult( |
| 575 | + tls_cred, |
| 576 | + msg='linked_to_cluster id not valid', |
| 577 | + status={ |
| 578 | + 'unknown_id': tls_cred.linked_to_cluster, |
| 579 | + }, |
| 580 | + ) |
| 581 | + |
| 582 | + |
| 583 | +def _tls_ref(src: Optional[resources.TLSSource]) -> str: |
| 584 | + if src and src.source_type == UserGroupSourceType.RESOURCE and src.ref: |
| 585 | + return src.ref |
| 586 | + return '' |
| 587 | + |
| 588 | + |
| 589 | +def tls_refs(cluster: resources.Cluster) -> Collection[str]: |
| 590 | + if not cluster.remote_control: |
| 591 | + return set() |
| 592 | + refs = ( |
| 593 | + _tls_ref(s) |
| 594 | + for s in ( |
| 595 | + cluster.remote_control.cert, |
| 596 | + cluster.remote_control.key, |
| 597 | + cluster.remote_control.ca_cert, |
| 598 | + ) |
| 599 | + ) |
| 600 | + return {ref for ref in refs if ref} |
| 601 | + |
| 602 | + |
535 | 603 | def _parse_earmark(earmark: str) -> dict: |
536 | 604 | parts = earmark.split('.') |
537 | 605 |
|
|
0 commit comments