]>
git.proxmox.com Git - ceph.git/blob - ceph/src/python-common/ceph/deployment/hostspec.py
1 from collections
import OrderedDict
4 from typing
import Optional
, List
, Any
, Dict
6 pass # just for type checking
9 class SpecValidationError(Exception):
11 Defining an exception here is a bit problematic, cause you cannot properly catch it,
12 if it was raised in a different mgr module.
16 errno
: int = -errno
.EINVAL
):
17 super(SpecValidationError
, self
).__init
__(msg
)
21 class HostSpec(object):
23 Information about hosts. Like e.g. ``kubectl get nodes``
27 addr
: Optional
[str] = None,
28 labels
: Optional
[List
[str]] = None,
29 status
: Optional
[str] = None,
30 location
: Optional
[Dict
[str, str]] = None,
32 self
.service_type
= 'host'
34 #: the bare hostname on the host. Not the FQDN.
35 self
.hostname
= hostname
# type: str
37 #: DNS name or IP address to reach it
38 self
.addr
= addr
or hostname
# type: str
41 self
.labels
= labels
or [] # type: List[str]
43 #: human readable status
44 self
.status
= status
or '' # type: str
46 self
.location
= location
48 def to_json(self
) -> Dict
[str, Any
]:
50 'hostname': self
.hostname
,
52 'labels': list(OrderedDict
.fromkeys((self
.labels
))),
53 'status': self
.status
,
56 r
['location'] = self
.location
60 def from_json(cls
, host_spec
: dict) -> 'HostSpec':
61 host_spec
= cls
.normalize_json(host_spec
)
63 host_spec
['hostname'],
64 host_spec
['addr'] if 'addr' in host_spec
else None,
65 list(OrderedDict
.fromkeys(
66 host_spec
['labels'])) if 'labels' in host_spec
else None,
67 host_spec
['status'] if 'status' in host_spec
else None,
68 host_spec
.get('location'),
73 def normalize_json(host_spec
: dict) -> dict:
74 labels
= host_spec
.get('labels')
75 if labels
is not None:
76 if isinstance(labels
, str):
77 host_spec
['labels'] = [labels
]
79 not isinstance(labels
, list)
80 or any(not isinstance(v
, str) for v
in labels
)
82 raise SpecValidationError(
83 f
'Labels ({labels}) must be a string or list of strings'
86 loc
= host_spec
.get('location')
89 not isinstance(loc
, dict)
90 or any(not isinstance(k
, str) for k
in loc
.keys())
91 or any(not isinstance(v
, str) for v
in loc
.values())
93 raise SpecValidationError(
94 f
'Location ({loc}) must be a dictionary of strings to strings'
99 def __repr__(self
) -> str:
100 args
= [self
.hostname
] # type: List[Any]
101 if self
.addr
is not None:
102 args
.append(self
.addr
)
104 args
.append(self
.labels
)
106 args
.append(self
.status
)
108 args
.append(self
.location
)
110 return "HostSpec({})".format(', '.join(map(repr, args
)))
112 def __str__(self
) -> str:
113 if self
.hostname
!= self
.addr
:
114 return f
'{self.hostname} ({self.addr})'
117 def __eq__(self
, other
: Any
) -> bool:
118 # Let's omit `status` for the moment, as it is still the very same host.
119 return self
.hostname
== other
.hostname
and \
120 self
.addr
== other
.addr
and \
121 sorted(self
.labels
) == sorted(other
.labels
) and \
122 self
.location
== other
.location