Skip to content

Commit 5ec86b6

Browse files
authored
Merge pull request ceph#65567 from rkachach/fix_issue_certs_migration
mgr/cephadm: cleaning up old migration logic and improving upgrade handling with certmgr Reviewed-by: Adam King <[email protected]>
2 parents 1076450 + 786f28c commit 5ec86b6

File tree

5 files changed

+19
-89
lines changed

5 files changed

+19
-89
lines changed

src/pybind/mgr/cephadm/inventory.py

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
from mgr_util import parse_combined_pem_file
2828

2929
from .utils import resolve_ip, SpecialHostLabels
30-
from .migrations import queue_migrate_nfs_spec, queue_migrate_rgw_spec, queue_migrate_rgw_ssl_spec
30+
from .migrations import queue_migrate_nfs_spec, queue_migrate_rgw_spec
3131

3232
if TYPE_CHECKING:
3333
from .module import CephadmOrchestrator
@@ -309,12 +309,6 @@ def load(self):
309309
):
310310
queue_migrate_rgw_spec(self.mgr, j)
311311

312-
if (
313-
(self.mgr.migration_current or 0) < 8
314-
and j['spec'].get('service_type') == 'rgw'
315-
):
316-
queue_migrate_rgw_ssl_spec(self.mgr, j)
317-
318312
spec = ServiceSpec.from_json(j['spec'])
319313
created = str_to_datetime(cast(str, j['created']))
320314
self._specs[service_name] = spec

src/pybind/mgr/cephadm/migrations.py

Lines changed: 6 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,15 @@
77
from cephadm.schedule import HostAssignment
88
from cephadm.utils import SpecialHostLabels
99
import rados
10-
from mgr_util import parse_combined_pem_file, get_cert_issuer_info
11-
from cephadm.tlsobject_types import CertKeyPair
10+
from mgr_util import get_cert_issuer_info
1211

1312
from mgr_module import NFS_POOL_NAME
1413
from orchestrator import OrchestratorError, DaemonDescription
1514

1615
if TYPE_CHECKING:
1716
from .module import CephadmOrchestrator
1817

19-
LAST_MIGRATION = 9
18+
LAST_MIGRATION = 8
2019

2120
logger = logging.getLogger(__name__)
2221

@@ -43,9 +42,6 @@ def __init__(self, mgr: "CephadmOrchestrator"):
4342
r = mgr.get_store('rgw_migration_queue')
4443
self.rgw_migration_queue = json.loads(r) if r else []
4544

46-
r = mgr.get_store('rgw_ssl_migration_queue')
47-
self.rgw_ssl_migration_queue = json.loads(r) if r else []
48-
4945
# for some migrations, we don't need to do anything except for
5046
# incrementing migration_current.
5147
# let's try to shortcut things here.
@@ -126,11 +122,6 @@ def migrate(self, startup: bool = False) -> None:
126122
if self.migrate_7_8():
127123
self.set(8)
128124

129-
if self.mgr.migration_current == 8:
130-
logger.info('Running migration 8 -> 9')
131-
if self.migrate_8_9():
132-
self.set(9)
133-
134125
def migrate_0_1(self) -> bool:
135126
"""
136127
Migration 0 -> 1
@@ -455,16 +446,12 @@ def migrate_6_7(self) -> bool:
455446
grafana_cert = self.mgr.get_store(grafana_cert_path)
456447
grafana_key = self.mgr.get_store(grafana_key_path)
457448
if grafana_cert:
458-
(org, cn) = get_cert_issuer_info(grafana_cert)
459-
if org == 'Ceph':
460-
logger.info(f'Migrating {grafana_daemon.name()}/{hostname} cert/key to cert store (as cephadm-signed certs)')
461-
self.mgr.cert_mgr.register_self_signed_cert_key_pair('grafana')
462-
self.mgr.cert_mgr.save_self_signed_cert_key_pair('grafana', CertKeyPair(grafana_cert, grafana_key), host=hostname)
463-
else:
449+
org, _ = get_cert_issuer_info(grafana_cert)
450+
if org != 'Ceph':
464451
logger.info(f'Migrating {grafana_daemon.name()}/{hostname} cert/key to cert store (as custom-certs)')
465452
grafana_cephadm_signed_certs = False
466-
self.mgr.cert_mgr.save_cert('grafana_ssl_cert', grafana_cert, host=hostname)
467-
self.mgr.cert_mgr.save_key('grafana_ssl_key', grafana_key, host=hostname)
453+
self.mgr.cert_mgr.save_cert('grafana_ssl_cert', grafana_cert, host=hostname, user_made=True, editable=True)
454+
self.mgr.cert_mgr.save_key('grafana_ssl_key', grafana_key, host=hostname, user_made=True, editable=True)
468455

469456
if not grafana_cephadm_signed_certs:
470457
# Update the spec to specify the right certificate source
@@ -478,37 +465,6 @@ def migrate_6_7(self) -> bool:
478465
return True
479466

480467
def migrate_7_8(self) -> bool:
481-
logger.info(f'Starting rgw SSL/TLS migration (queue length is {len(self.rgw_ssl_migration_queue)})')
482-
for s in self.rgw_ssl_migration_queue:
483-
484-
svc_spec = s['spec'] # this is the RGWspec
485-
486-
if 'spec' not in svc_spec:
487-
logger.info(f"No SSL/TLS fields migration is needed for rgw spec: {svc_spec}")
488-
continue
489-
490-
cert_field = svc_spec['spec'].get('rgw_frontend_ssl_certificate')
491-
if not cert_field:
492-
logger.info(f"No SSL/TLS fields migration is needed for rgw spec: {svc_spec}")
493-
continue
494-
495-
cert_str = '\n'.join(cert_field) if isinstance(cert_field, list) else cert_field
496-
ssl_cert, ssl_key = parse_combined_pem_file(cert_str)
497-
new_spec = svc_spec.copy()
498-
new_spec['spec'].update({
499-
'rgw_frontend_ssl_certificate': None,
500-
'certificate_source': CertificateSource.INLINE.value,
501-
'ssl_cert': ssl_cert,
502-
'ssl_key': ssl_key,
503-
})
504-
505-
logger.info(f"Migrating {svc_spec} to new RGW SSL/TLS format {new_spec}")
506-
self.mgr.spec_store.save(RGWSpec.from_json(new_spec))
507-
508-
self.rgw_ssl_migration_queue = []
509-
return True
510-
511-
def migrate_8_9(self) -> bool:
512468
"""
513469
Replace Promtail with Alloy.
514470
@@ -588,15 +544,6 @@ def queue_migrate_rgw_spec(mgr: "CephadmOrchestrator", spec_dict: Dict[Any, Any]
588544
logger.info(f'Queued rgw.{service_id} for migration')
589545

590546

591-
def queue_migrate_rgw_ssl_spec(mgr: "CephadmOrchestrator", spec_dict: Dict[Any, Any]) -> None:
592-
service_id = spec_dict['spec']['service_id']
593-
queued = mgr.get_store('rgw_ssl_migration_queue') or '[]'
594-
ls = json.loads(queued)
595-
ls.append(spec_dict)
596-
mgr.set_store('rgw_ssl_migration_queue', json.dumps(ls))
597-
logger.info(f'Queued rgw.{service_id} for TLS migration')
598-
599-
600547
def queue_migrate_nfs_spec(mgr: "CephadmOrchestrator", spec_dict: Dict[Any, Any]) -> None:
601548
"""
602549
After 16.2.5 we dropped the NFSServiceSpec pool and namespace properties.

src/pybind/mgr/cephadm/tests/test_migration.py

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
RGWSpec,
99
IngressSpec,
1010
IscsiServiceSpec,
11-
GrafanaSpec
11+
GrafanaSpec,
12+
CertificateSource
1213
)
1314
from ceph.utils import datetime_to_str, datetime_now
1415
from cephadm import CephadmOrchestrator
@@ -402,25 +403,6 @@ def test_migrate_rgw_spec(cephadm_module: CephadmOrchestrator, rgw_spec_store_en
402403
assert 'rgw.foo' not in cephadm_module.spec_store.all_specs
403404

404405

405-
@mock.patch('cephadm.migrations.get_cert_issuer_info')
406-
def test_migrate_grafana_cephadm_signed(mock_get_cert_issuer_info, cephadm_module: CephadmOrchestrator):
407-
mock_get_cert_issuer_info.return_value = ('Ceph', 'MockCephCN')
408-
409-
cephadm_module.set_store('host1/grafana_crt', 'grafana_cert1')
410-
cephadm_module.set_store('host1/grafana_key', 'grafana_key1')
411-
cephadm_module.set_store('host2/grafana_crt', 'grafana_cert2')
412-
cephadm_module.set_store('host2/grafana_key', 'grafana_key2')
413-
cephadm_module.cache.daemons = {'host1': {'grafana.host1': DaemonDescription('grafana', 'host1', 'host1')},
414-
'host2': {'grafana.host2': DaemonDescription('grafana', 'host2', 'host2')}}
415-
416-
cephadm_module.migration.migrate_6_7()
417-
418-
assert cephadm_module.cert_mgr.get_cert('cephadm-signed_grafana_cert', host='host1')
419-
assert cephadm_module.cert_mgr.get_cert('cephadm-signed_grafana_cert', host='host2')
420-
assert cephadm_module.cert_mgr.get_key('cephadm-signed_grafana_key', host='host1')
421-
assert cephadm_module.cert_mgr.get_key('cephadm-signed_grafana_key', host='host2')
422-
423-
424406
@mock.patch('cephadm.migrations.get_cert_issuer_info')
425407
def test_migrate_grafana_custom_certs(mock_get_cert_issuer_info, cephadm_module: CephadmOrchestrator):
426408
from datetime import datetime, timezone
@@ -445,6 +427,7 @@ def test_migrate_grafana_custom_certs(mock_get_cert_issuer_info, cephadm_module:
445427
assert cephadm_module.cert_mgr.get_cert('grafana_ssl_cert', host='host2')
446428
assert cephadm_module.cert_mgr.get_key('grafana_ssl_key', host='host1')
447429
assert cephadm_module.cert_mgr.get_key('grafana_ssl_key', host='host2')
430+
assert cephadm_module.spec_store._specs['grafana'].certificate_source == CertificateSource.REFERENCE.value
448431

449432

450433
def test_migrate_cert_store(cephadm_module: CephadmOrchestrator):

src/pybind/mgr/cephadm/utils.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,18 @@ class CephadmNoImage(Enum):
2727
GATEWAY_TYPES = ['iscsi', 'nfs', 'nvmeof', 'smb']
2828
MONITORING_STACK_TYPES = ['node-exporter', 'prometheus',
2929
'alertmanager', 'grafana', 'loki', 'promtail', 'alloy']
30+
MGMT_GATEWAY_STACK_TYPES = ['mgmt-gateway', 'oauth2-proxy']
3031
RESCHEDULE_FROM_OFFLINE_HOSTS_TYPES = ['haproxy', 'nfs']
3132

32-
CEPH_UPGRADE_ORDER = CEPH_TYPES + GATEWAY_TYPES + MONITORING_STACK_TYPES
33+
CEPH_UPGRADE_ORDER = CEPH_TYPES + GATEWAY_TYPES + MONITORING_STACK_TYPES + MGMT_GATEWAY_STACK_TYPES
3334

3435
# these daemon types use the ceph container image
3536
CEPH_IMAGE_TYPES = CEPH_TYPES + ['iscsi', 'nfs', 'node-proxy']
3637

3738
# these daemons do not use the ceph image. There are other daemons
3839
# that also don't use the ceph image, but we only care about those
3940
# that are part of the upgrade order here
40-
NON_CEPH_IMAGE_TYPES = MONITORING_STACK_TYPES + ['nvmeof', 'smb']
41+
NON_CEPH_IMAGE_TYPES = MONITORING_STACK_TYPES + ['nvmeof', 'smb'] + MGMT_GATEWAY_STACK_TYPES
4142

4243
# Used for _run_cephadm used for check-host etc that don't require an --image parameter
4344
cephadmNoImage = CephadmNoImage.token

src/python-common/ceph/deployment/service_spec.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1520,17 +1520,22 @@ def get_port(self) -> List[int]:
15201520
return ports
15211521

15221522
def validate(self) -> None:
1523-
super(RGWSpec, self).validate()
15241523

15251524
if self.ssl:
15261525
if not self.ssl_cert and self.rgw_frontend_ssl_certificate:
15271526
combined_cert = self.rgw_frontend_ssl_certificate
15281527
if isinstance(combined_cert, list):
15291528
combined_cert = '\n'.join(combined_cert)
1529+
self.certificate_source = CertificateSource.INLINE.value
15301530
self.ssl_cert, self.ssl_key = parse_combined_pem_file(combined_cert)
1531+
self.rgw_frontend_ssl_certificate = None
15311532
if not (self.ssl_cert and self.ssl_key):
15321533
raise SpecValidationError("Failed to parse rgw_frontend_ssl_certificate field.")
15331534

1535+
# This validation is done after adjusting the SSL field so when
1536+
# RGW Spec is updated with the right fields before validation
1537+
super(RGWSpec, self).validate()
1538+
15341539
if self.rgw_realm and not self.rgw_zone:
15351540
raise SpecValidationError(
15361541
'Cannot add RGW: Realm specified but no zone specified')

0 commit comments

Comments
 (0)