from ceph.deployment.inventory import Device
from ceph.deployment.drive_group import DriveGroupSpec, DeviceSelection
-from ceph.deployment.service_spec import PlacementSpec, ServiceSpec, \
+from ceph.deployment.service_spec import PlacementSpec, ServiceSpec, service_spec_allow_invalid_from_json, \
SNMPGatewaySpec
from ceph.deployment.hostspec import SpecValidationError
from ceph.utils import datetime_now
if len(services) == 0:
return HandleCommandResult(stdout="No services reported")
elif format != Format.plain:
- if export:
- data = [s.spec for s in services if s.deleted is None]
- return HandleCommandResult(stdout=to_format(data, format, many=True, cls=ServiceSpec))
- else:
- return HandleCommandResult(stdout=to_format(services, format, many=True, cls=ServiceDescription))
+ with service_spec_allow_invalid_from_json():
+ if export:
+ data = [s.spec for s in services if s.deleted is None]
+ return HandleCommandResult(stdout=to_format(data, format, many=True, cls=ServiceSpec))
+ else:
+ return HandleCommandResult(stdout=to_format(services, format, many=True, cls=ServiceDescription))
else:
now = datetime_now()
table = PrettyTable(
from __future__ import absolute_import
import json
+import textwrap
import pytest
import yaml
'osd 123 - - '
assert r == HandleCommandResult(retval=0, stdout=out, stderr='')
+ cmd = {
+ 'prefix': 'orch ls',
+ 'format': 'yaml',
+ }
+ m = OrchestratorCli('orchestrator', 0, 0)
+ r = m._handle_command(None, cmd)
+ out = textwrap.dedent("""
+ service_type: osd
+ service_name: osd
+ spec:
+ filter_logic: AND
+ objectstore: bluestore
+ status:
+ running: 123
+ size: 0
+ """).lstrip()
+ assert r == HandleCommandResult(retval=0, stdout=out, stderr='')
+
def test_preview_table_osd_smoke():
data = [
import re
import enum
from collections import OrderedDict
+from contextlib import contextmanager
from functools import wraps
from ipaddress import ip_network, ip_address
from typing import Optional, Dict, Any, List, Union, Callable, Iterable, Type, TypeVar, cast, \
- NamedTuple, Mapping
+ NamedTuple, Mapping, Iterator
import yaml
return ps
+_service_spec_from_json_validate = True
+
+
+@contextmanager
+def service_spec_allow_invalid_from_json() -> Iterator[None]:
+ """
+ I know this is evil, but unfortunately `ceph orch ls`
+ may return invalid OSD specs for OSDs not associated to
+ and specs. If you have a better idea, please!
+ """
+ global _service_spec_from_json_validate
+ _service_spec_from_json_validate = False
+ yield
+ _service_spec_from_json_validate = True
+
+
class ServiceSpec(object):
"""
Details of service creation.
:meta private:
"""
-
if not isinstance(json_spec, dict):
raise SpecValidationError(
f'Service Spec is not an (JSON or YAML) object. got "{str(json_spec)}"')
continue
args.update({k: v})
_cls = cls(**args)
- _cls.validate()
+ if _service_spec_from_json_validate:
+ _cls.validate()
return _cls
def service_name(self) -> str: