Skip to content

Commit 0c84675

Browse files
mihaelabalutoiuDany9966
authored andcommitted
Display licence editions in the licensing CLI
The appliance licensing status now carries a separate set of usage counters for each licence edition, and licences and reservations identify the edition they belong to. Signed-off-by: Mihaela Balutoiu <mbalutoiu@cloudbasesolutions.com>
1 parent 73ab480 commit 0c84675

4 files changed

Lines changed: 112 additions & 50 deletions

File tree

coriolisclient/cli/licensing.py

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from cliff import show
2121

2222
from coriolisclient.cli import formatter
23+
from coriolisclient import constants
2324

2425

2526
class LicensingStatusFormatter(formatter.EntityFormatter):
@@ -29,29 +30,26 @@ def __init__(self):
2930
"appliance_id",
3031
"earliest_licence_expiry_time",
3132
"latest_licence_expiry_time",
32-
"current_performed_migrations",
33-
"current_performed_replicas",
34-
"current_available_migrations",
35-
"current_available_replicas",
36-
"lifetime_performed_migrations",
37-
"lifetime_performed_replicas",
38-
"lifetime_available_migrations",
39-
"lifetime_available_replicas",
4033
]
34+
self.columns.extend(
35+
"standard_%s" % field
36+
for field in constants.LICENCE_STATS_FIELDS)
37+
self.columns.extend(
38+
"sap_%s" % field for field in constants.LICENCE_STATS_FIELDS)
4139

4240
def _get_formatted_data(self, obj):
41+
standard_stats = getattr(obj, constants.LICENCE_STATS_KEY_STANDARD)
42+
sap_stats = getattr(obj, constants.LICENCE_STATS_KEY_SAP)
43+
4344
data = [obj.appliance_id,
4445
obj.earliest_licence_expiry_time,
4546
obj.latest_licence_expiry_time,
46-
obj.current_performed_migrations,
47-
obj.current_performed_replicas,
48-
obj.current_available_migrations,
49-
obj.current_available_replicas,
50-
obj.lifetime_performed_migrations,
51-
obj.lifetime_performed_replicas,
52-
obj.lifetime_available_migrations,
53-
obj.lifetime_available_replicas,
5447
]
48+
data.extend(
49+
standard_stats[field]
50+
for field in constants.LICENCE_STATS_FIELDS)
51+
data.extend(
52+
sap_stats[field] for field in constants.LICENCE_STATS_FIELDS)
5553

5654
return data
5755

@@ -65,6 +63,7 @@ class LicenceFormatter(formatter.EntityFormatter):
6563
"Period End",
6664
"Period Duration",
6765
"Licence Version",
66+
"Licence Edition",
6867
)
6968

7069
def _get_sorted_list(self, obj_list):
@@ -79,6 +78,8 @@ def _get_formatted_data(self, obj):
7978
obj.period_end,
8079
obj.period_duration,
8180
obj.licence_version,
81+
constants.LICENCE_TYPE_EDITION_MAP.get(
82+
obj.licence_version),
8283
)
8384

8485
return data

coriolisclient/cli/licensing_reservations.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@
1717
from cliff import show
1818

1919
from coriolisclient.cli import formatter
20+
from coriolisclient import constants
2021

2122

2223
class ReservationFormatter(formatter.EntityFormatter):
2324
columns = ("ID",
2425
"Appliance ID",
2526
"Licence ID",
2627
"Type",
28+
"Licence Edition",
2729
"Count",
2830
"Created At",
2931
)
@@ -36,6 +38,7 @@ def _get_formatted_data(self, obj):
3638
obj.appliance_id,
3739
obj.licence_id,
3840
obj.type,
41+
constants.RESERVATION_TYPE_EDITION_MAP.get(obj.type),
3942
obj.count,
4043
obj.created_at,
4144
)

coriolisclient/tests/cli/test_licensing.py

Lines changed: 72 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from cliff import show
99

1010
from coriolisclient.cli import licensing
11+
from coriolisclient import constants
1112
from coriolisclient.tests import test_base
1213

1314

@@ -18,29 +19,42 @@ def setUp(self):
1819
super(LicensingStatusFormatterTestCase, self).setUp()
1920
self.licence = licensing.LicensingStatusFormatter()
2021

21-
def test_get_formatted_data(self):
22+
@staticmethod
23+
def _make_stats(offset):
24+
"""Builds a stats body whose counters are all distinguishable."""
25+
return {
26+
field: offset + i
27+
for i, field in enumerate(constants.LICENCE_STATS_FIELDS)}
28+
29+
def _make_status(self, standard_stats, sap_stats):
2230
obj = mock.Mock()
2331
obj.appliance_id = mock.sentinel.appliance_id
2432
obj.earliest_licence_expiry_time = \
2533
mock.sentinel.earliest_licence_expiry_time
2634
obj.latest_licence_expiry_time = \
2735
mock.sentinel.latest_licence_expiry_time
28-
obj.current_performed_migrations = \
29-
mock.sentinel.current_performed_migrations
30-
obj.current_performed_replicas = \
31-
mock.sentinel.current_performed_replicas
32-
obj.current_available_migrations = \
33-
mock.sentinel.current_available_migrations
34-
obj.current_available_replicas = \
35-
mock.sentinel.current_available_replicas
36-
obj.lifetime_performed_migrations = \
37-
mock.sentinel.lifetime_performed_migrations
38-
obj.lifetime_performed_replicas = \
39-
mock.sentinel.lifetime_performed_replicas
40-
obj.lifetime_available_migrations = \
41-
mock.sentinel.lifetime_available_migrations
42-
obj.lifetime_available_replicas = \
43-
mock.sentinel.lifetime_available_replicas
36+
setattr(obj, constants.LICENCE_STATS_KEY_STANDARD, standard_stats)
37+
setattr(obj, constants.LICENCE_STATS_KEY_SAP, sap_stats)
38+
return obj
39+
40+
def test_columns(self):
41+
self.assertEqual(
42+
[
43+
"appliance_id",
44+
"earliest_licence_expiry_time",
45+
"latest_licence_expiry_time",
46+
] + [
47+
"standard_%s" % f for f in constants.LICENCE_STATS_FIELDS
48+
] + [
49+
"sap_%s" % f for f in constants.LICENCE_STATS_FIELDS
50+
],
51+
self.licence.columns
52+
)
53+
54+
def test_get_formatted_data(self):
55+
standard_stats = self._make_stats(0)
56+
sap_stats = self._make_stats(100)
57+
obj = self._make_status(standard_stats, sap_stats)
4458

4559
result = self.licence._get_formatted_data(obj)
4660

@@ -49,17 +63,30 @@ def test_get_formatted_data(self):
4963
mock.sentinel.appliance_id,
5064
mock.sentinel.earliest_licence_expiry_time,
5165
mock.sentinel.latest_licence_expiry_time,
52-
mock.sentinel.current_performed_migrations,
53-
mock.sentinel.current_performed_replicas,
54-
mock.sentinel.current_available_migrations,
55-
mock.sentinel.current_available_replicas,
56-
mock.sentinel.lifetime_performed_migrations,
57-
mock.sentinel.lifetime_performed_replicas,
58-
mock.sentinel.lifetime_available_migrations,
59-
mock.sentinel.lifetime_available_replicas
66+
] + [
67+
standard_stats[f] for f in constants.LICENCE_STATS_FIELDS
68+
] + [
69+
sap_stats[f] for f in constants.LICENCE_STATS_FIELDS
6070
],
6171
result
6272
)
73+
self.assertEqual(len(self.licence.columns), len(result))
74+
75+
def test_get_formatted_data_standard_only(self):
76+
standard_stats = self._make_stats(0)
77+
sap_stats = dict.fromkeys(constants.LICENCE_STATS_FIELDS, 0)
78+
obj = self._make_status(standard_stats, sap_stats)
79+
80+
result = self.licence._get_formatted_data(obj)
81+
82+
self.assertEqual(
83+
[standard_stats[f] for f in constants.LICENCE_STATS_FIELDS],
84+
result[3:3 + len(constants.LICENCE_STATS_FIELDS)]
85+
)
86+
self.assertEqual(
87+
[0] * len(constants.LICENCE_STATS_FIELDS),
88+
result[-len(constants.LICENCE_STATS_FIELDS):]
89+
)
6390

6491

6592
class LicenceFormatterTestCase(test_base.CoriolisBaseTestCase):
@@ -85,7 +112,7 @@ def test_get_sorted_list(self):
85112
result
86113
)
87114

88-
def test_get_formatted_data(self):
115+
def _assert_formatted(self, licence_version, licence_edition):
89116
obj = mock.Mock()
90117
obj.id = mock.sentinel.id
91118
obj.issue_date = mock.sentinel.issue_date
@@ -94,9 +121,7 @@ def test_get_formatted_data(self):
94121
obj.period_start = mock.sentinel.period_start
95122
obj.period_end = mock.sentinel.period_end
96123
obj.period_duration = mock.sentinel.period_duration
97-
obj.licence_version = mock.sentinel.licence_version
98-
99-
result = self.licence._get_formatted_data(obj)
124+
obj.licence_version = licence_version
100125

101126
self.assertEqual(
102127
(
@@ -107,11 +132,27 @@ def test_get_formatted_data(self):
107132
mock.sentinel.period_start,
108133
mock.sentinel.period_end,
109134
mock.sentinel.period_duration,
110-
mock.sentinel.licence_version
135+
licence_version,
136+
licence_edition,
111137
),
112-
result
138+
self.licence._get_formatted_data(obj)
113139
)
114140

141+
def test_get_formatted_data(self):
142+
self._assert_formatted(
143+
constants.LICENCE_VERSION_V2, constants.LICENCE_EDITION_STANDARD)
144+
145+
def test_get_formatted_data_sap(self):
146+
self._assert_formatted(
147+
constants.LICENCE_VERSION_V2_SAP, constants.LICENCE_EDITION_SAP)
148+
149+
def test_get_formatted_data_v1(self):
150+
self._assert_formatted(
151+
constants.LICENCE_VERSION_V1, constants.LICENCE_EDITION_STANDARD)
152+
153+
def test_get_formatted_data_unknown_version(self):
154+
self._assert_formatted("v3-something", None)
155+
115156

116157
class LicensingApplianceStatusTestCase(test_base.CoriolisBaseTestCase):
117158
"""Test suite for the Coriolis Client Licensing Appliance Status."""

coriolisclient/tests/cli/test_licensing_reservations.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from cliff import show
88

99
from coriolisclient.cli import licensing_reservations
10+
from coriolisclient import constants
1011
from coriolisclient.tests import test_base
1112

1213

@@ -33,12 +34,12 @@ def test_get_sorted_list(self):
3334
result
3435
)
3536

36-
def test_get_formatted_data(self):
37+
def _assert_formatted(self, reservation_type, licence_edition):
3738
obj = mock.Mock()
3839
obj.id = mock.sentinel.id
3940
obj.appliance_id = mock.sentinel.appliance_id
4041
obj.licence_id = mock.sentinel.licence_id
41-
obj.type = mock.sentinel.type
42+
obj.type = reservation_type
4243
obj.count = mock.sentinel.count
4344
obj.created_at = mock.sentinel.created_at
4445

@@ -49,13 +50,29 @@ def test_get_formatted_data(self):
4950
mock.sentinel.id,
5051
mock.sentinel.appliance_id,
5152
mock.sentinel.licence_id,
52-
mock.sentinel.type,
53+
reservation_type,
54+
licence_edition,
5355
mock.sentinel.count,
5456
mock.sentinel.created_at
5557
),
5658
result
5759
)
5860

61+
def test_get_formatted_data(self):
62+
for reservation_type in [constants.RESERVATION_TYPE_REPLICA,
63+
constants.RESERVATION_TYPE_MIGRATION]:
64+
self._assert_formatted(
65+
reservation_type, constants.LICENCE_EDITION_STANDARD)
66+
67+
def test_get_formatted_data_sap(self):
68+
for reservation_type in [constants.RESERVATION_TYPE_SAP_REPLICA,
69+
constants.RESERVATION_TYPE_SAP_MIGRATION]:
70+
self._assert_formatted(
71+
reservation_type, constants.LICENCE_EDITION_SAP)
72+
73+
def test_get_formatted_data_unknown_type(self):
74+
self._assert_formatted("something", None)
75+
5976

6077
class ReservationListTestCase(test_base.CoriolisBaseTestCase):
6178
"""Test suite for the Coriolis Client Reservation List."""

0 commit comments

Comments
 (0)